Follow Queue: Java 1.5 Add a new data structure interface
The Java 1.5 version finally provides intrinsic support for one of the most basic data structures in the program. This article explores the Queue interface added to the java.util package, demonstrate how to use this new feature to make your data process flow.
By Kulvir Singh Bhogal
Translated by Victor Jan 2004-09-26)
(English original
http://www.devx.com/java/Article/21983/1954?pf=true)
In computer discipline, one of the basic data structures - Queue. You will think of Queue is a data structure, and the elements inside it can be removed in the same order of adding them. In the previous Java version, this FIFO (advanced first out) data structure is unfortunately ignored. With the emergence of Java1.5 (also called Tiger), Queue supports the first time a natural feature. How to manage if there is no queue? Before Java 1.5, the usual implementation is to imitate Queue using java.util.list collection. The concept of QUEUE is removed by adding an object to the end of the object to the tail of the List (ie, the rear of the queue) and removes the object from the head of the List (ie, the front of the queue) (called DEQUEUING operations to simulate. The following code shows your previous possible practices.
Import java.util.enumeration;
Import java.util.linkedList;
Import java.util.vector;
Public class queueemulate
{
Private linkedlist queuemembers;
Public Object Enqueue (Object Element)
{
Queuemembers.Add (element);
Return Element;
}
Public Object Dequeue ()
{
Return queuemembers.removefirst ();
}
}
Now we have Queue Java 1.5 to add a Queue interface in the java.util package, which is used in the following code (intercept from Sample Code's SimpleueueUSageexample.java). Note that in Java 1.5, java.util.LinkedList is used to implement java.util.Queue, just like a java.util.list interface. Also pay attention to how I explicitly declare that I only contain queue, using the string - use
Queue
MyQueue.Add ("Add ME");
MyQueue.Add ("Add Me Too");
String enqueued = myQueue.remove ();
You can see the Add and Remove methods of the LinkedList class are used to perform Enqueuing and Dequeing operations, respectively. There is no better availability method; the Queue interface provides new OFFER and POLL methods, as shown below (intercepting SIMPLEQUEUSAGEXAMPREFERRED): Queue
Boolean offersuccess;
// Offer method Tries to enquue.
// a boolean is returned telling you if the
// attempt to add to the queue Was successful or not
Offersuccess = MyQueue.offer ("Add ME");
Offersuccess = MyQueue.offer ("Add me too");
// peek at the head of the queue, but don't grab it
Object pull = myQueue.peek ();
String enqueued = NULL;
// grab the head of the queue
IF (PULL! = null) enqueued = myqueue.poll ();
System.out.println (enqueued);
If your Queue has a fixed length restriction (often this situation), use the add method to add content to Queue, which will result in a non-check exception. When you compile the SimpleueUserusageExample, the compiler will issue a warning on this issue. Instead, when the new OFFER method is trying to add, if everything is normal, returns True, otherwise, returns false. Similarly, if you try to use the REMOVE method to operate an empty Queue, it will also cause a non-check exception. You can also use the Poll method to extract the elements from Queue. If there is no element in Queue, the poll method will return a NULL (ie no exception). In some cases, you may not want to extract the elements of the head and just want to look at it. The Queue interface provides a PEEK method to do this. If you are processing an empty Queue, the PEEK method returns NULL. As with the ADD-OFFER and REMOVE-POLL relationship, there is a PEEK-Element relationship. In the case of queue, the ELEMENT method throws a non-check exception. But if there is element in Queue, the PEEK method allows you to check the first element without having to take him from Queue. The Usage of the PEEK method has an example in the SimplequeueusageExamplepreferred class.
The AbstractQueue class is as you can see, the Java.util.LinkedList class implements the java.util.queue interface, the same, AbstractQueue is also the case. The AbstractQueue class implements some methods of the Java.util interface (so containing Abstract in its name). AbstractQueue will focus on implementations of Offer, Poll, and Peek methods. Also use some specific implementations already provided. PriorityQueue class In PriorityQueue, automatic sorting is achieved when you add an element to Queue. Depending on the different constructor of the priorityQueue you use, the order in which the queue element is either based on their natural order, either through the PrioriRiRiRiRiRiRtyqueue constructor, is determined. The following code exemplifies how the PirorityQueue class is used. The front side of the Queue is a string "alabama" - Since the element is arranged in natural order (in this example, in this example is sequence). PriorityQueue
PriorityQueue.offer ("texas");
PriorityQueue.offer ("alabama");
PriorityQueue.offer ("California");
PriorityQueue.offer ("rhode island");
INT QueueSize = priorityQueue.size ();
For (int i = 0; i { System.out.println (priorityQueue.poll ()); } The execution results are as follows: Alabama California Rhode island Texas Queue is arranged in accordance with natural order - alphabetical sequence. As mentioned above, you can create your own Comprator class and provide PirorityQueue. So, you can define your own sorting. This method can be found in the PriorityQueueComparatorusageexample class where a helper class named State is used. As you can see below, in the class definition, State simply contains a name and population. PRIVATE STRING NAME; PRIVATE INT POPULATION; Public State (String Name, int Population) { Super (); THIS.NAME = Name; THIS.POPULATION = Population; } Public string getName () { Return this.name; } Public int getPopulation () { Return this.Population; } Public String Tostring () { Return getName () "-" getPopulation (); } In PriorityQueueComparatorusageexample, Queue uses the custom implementation of Java.util.comParetor to define the order (below). PriorityQueue New PriorityQueue (6, New Comparator Public Int Compare (State A, State B) { System.out.println ("Comparing Populations"); INT populationa = a.getpopulation (); INT populationb = B.GetPopulation (); IF (PopulationB> Populationa) Return 1; Else IF (PopulationB Return -1; Else Return 0; } } ); Once the PriorityQueueComparatorusageexample class is executed, the State object added to Queue will be discharged by the population (from low to high). Block Queue Queue is typically limited to a given size. So far, through Queue's implementation you have seen, use Offer or Add Method Enqueue Queue (and use Remove or Poll Queue "is assumed that if Queue cannot provide addition or removal operation, then you don't need to wait for the program. Java.util.concurrent.blockingQueue interface implementation. It adds PUT and Take methods. To give an example may be more useful. Using the original Producter / Consumer relationship to assume your producter writing a Queue (more specific is a blockingQueue). You have some consumer to read from Queue, which way is what you want to see in an ordered mode. Basically, each consUmer needs to wait for the first Consumer that is prior to it and is allowed to extract the project from Queue. Build this structure with programs, gentleman is used to write data to a queue, then generate some consumer threads to read data from the same queue. Note that the thread will block another thread until the current thread has completed an operation from Queue. The following code shows the process of writing BlockingQueue in class product. Note that the objects in the RUN method (you have a responsibility implementation, because you inherited Thread) After waiting for the random number (range from 100 to 500 milliseconds), it is put into the blockingQueue. The object in Queue is just some strings that contain time when the message is generated. The actual work of adding an object is implemented by the following statement: blocking queue.put ("Enqueued At: Time) PUT method throws InterruptedException, so the PUT operation needs to be surrounded by the try ... catch block, used to capture the thrown Exception (see Listing 1). Extracting the message from the Producter is the consumer object, which also inherits from the Thread object and therefore to implement the RUN method (see Listing 2). The consumer class is designed to be similar to the Producter class. The Consumer class uses the Take method to remove (ie the Dequeue "message from Queue instead of putting the message in the BlockingQueue. As mentioned earlier, this needs to wait for any content that does exist in Queue. If the Producter thread stops (ie, enqueue) objects to Queue, then Consumer will wait until Queue's project is valid. The TestBlockingQueue class shown below produces four consumer threads that try to extract objects from blockingQueue. Import java.util.concurrent.blockingQueue; import java.util.concurrent.linkedblockingQueue; Public Class TestblockingQueue { Public static void main (string args []) { Blockingqueue Producer Producter = New Producter (BlockingQueue, System.Out); Consumer Consumera = New Consumer ("Consumera", BlockingQueue, System.out); Consumer Consumerb = New Consumer ("Consumerb", BlockingQueue, System.out; Consumer Consumerc = New Consumer ("Consumerc", BlockingQueue, System.out; Consumer consumerd = new consumer ("consumerd", blockingQueue, system.out); Producer.start (); Consumera.start (); Consumerb.start (); Consumerc.start (); Consumerd.start (); } } Figure 1. Consumer threads: The Blockingqueue in The Order That You Spawned Them. Create blockingQueue: Blockingqueue Note that it uses BlockingQueue's LinkedBlockingQueue implementation. This is because BlockingQueue is an abstract class that you can't instantiate it directly. You can also use the ArrayBlockingQueuequeue type. ArrayBlockingQueue uses an array as its storage device, while LinkedBlockingQueue uses a LinkedList. The capacity of ArrayBlockingQueue is fixed. For LinkedBlockingQueue, the maximum value can be specified; the default is boundless. This example code uses a boundless way. During the execution of the class, the object is read from the Queue in order in order (see execution of the following example). In fact, a consumer thread blocks other threads accessing the BlockingQueue until it can take an object from Queue. DelayQueue - I / I don't have incomplete in some cases, stored in Queue in Queue, need to be placed in another queue before they are ready to be removed. At this point you can use the java.util.concurrent.delayQueue class, he implements the class blockingQueue interface. DELAYQUEUE requires a queue object to be resident in a specified time in Queue. I want to confirm its reality example (this may be you very eager) is about muffins. Oh, Muffin object (like the Java we are talking about without Coffee double reference). Assume that you have a DelayQueue and put some Muffin objects there. Muffin object (shown below) must implement a java.util.concurrent.delayed interface so that it can be placed in DelayQueue. This interface requires a muffin object to implement a getDelay method (as shown below). Getdelay method, actually declare how long it allows objects to save in DelayQueue. When the value returned by the method is 0 or less than 0, the object is ready (or in this example, it is baked) and allows it to be taken (see Listing 3). The MUFFIN class also implements the CompareTo (Java.util.concurrent.delayed) method. Because the delayed interface inherits from Java.lang.comParable classes, this will restrict the BakeCompletion time you want to implement the Muffin object. Because you don't really want to eat Muffin that is not fully roasted, it is necessary to put muffin to store the recommended baking time in DELAYQUEUE. Listing 4, taken from the DelayQueueUSAGexample class, showcase Enqueue and Dequeue Muffin objects from DELAYQUEUE. As you can see, the baking time for the Muffin object is set to use its constructor (the constructor expects the baking time in seconds). As before, Muffin objects are placed in DelayQueue, and they are not allowed until his delay time (called baking time) is over. The element is taken out from Queue Based on the earliest delay time. In this example, if you have some Muffin objects that have been grid, they will take it as long as they have been waiting (in other words, the earliest Muffin will be taken before the newly baked muffin). SynchronousQueue In Java 1.5, another block Queue implementation is Synchronousqueue. Quite interesting is that the Queue has no intrinsic capacity. This is deliberate because Queue is intended to pass the purpose. This means that in a synchronous queue structure, the PUT request must wait for the Take request from another thread. At the same time, a Take request must wait for a PUT request from another thread to SynchronousQueue. Use the program to exemplify this concept, see the sample code. Similar to the front LinkedBlockingQueue example, it contains a consumer (SynchConsumer), see Listing 5. The code in Listing 5 uses the Poll (Long Timeout, TimeUnit Unit) of the SYNCHRONOUSQUEUE class. This method allows the Poll process to wait for a specified time before waiting for another consumption thread to write SynchronousQueue (20 seconds in this example). PRODUCER (SynchProducer) in Listing 6 uses a similar Offer (E O, long timeout, timeunit unit) to place the object to SynchronousQueue. Use this method to allow for a period of time (10 seconds in this case) before you are tired to wait for another thread to read SynchronousQueue. Testsynchqueue demonstrates the action of Producer and Consumer: import java.util.concurrent.synchronousqueue; import java.util.concurrent.linkedBlockingQueue; Public Class testsynchqueue { Public static void main (string args []) { Synchronousqueue SynchProducer Producter = New SynchProducer ("Productra", Synchqueue, System.out); Synchconsumer consumera = new synchconsumer ("consumera", synchqueue, system.out; Consumera.start (); Producer.start (); } } When trying to understand the concept hidden behind SynchronousQueue, keep these queue usually used where it is used. Javadoc About synchronous Queue pointed out: "They [synchronous queue] is suitable for delivery design, where the object running in a thread must be synchronized with objects running in another thread to facilitate some information, time, or tasks ." About the Author: Kulvir Singh Bhogal is a consultant for IBM, planning and implements Java-Centric solutions on a customer site.