The queue interface is the same level as list and set, and both inherit the collection interface. LinkedList implements the queue interface. The queue interface narrows the access to the LinkedList method (that is, if the parameter type in the method is a queue, it is only possible to access the method defined by the queue interface and not directly to the LinkedList non-queue method). So that only appropriate methods can be used. Blockingqueue inherits the queue interface.
A queue is a data structure. It has two basic operations: adding an element to the tail of the queue, and removing an element from the head of the queue that is, the queue manages the data in a first-in, in-and-out manner if you attempt to add an element to an already full block queue or remove a single cell from an empty blocking queue, causing the thread to block. Blocking queues is a useful tool when working with multiple threads. Worker threads can periodically store intermediate results in a blocking queue while other worker thread threads take intermediate results out and modify them in the future. The queue automatically balances the load. If the first set of threads runs slower than the second, the second line threads blocks when it waits for the result. If the first set of threads runs fast, it waits for the second set of threads to catch up. The following table shows the actions of the blocking queue in jdk1.5:
AddAdd a single cable if the queue is full, throw a Iiiegaislabeepeplian exception
RemoveRemove and return elements of the queue header if the queue is empty, throws a Nosuchelementexception exception
elementReturns the element of the queue header if the queue is empty, a Nosuchelementexception exception is thrown
OfferAdds an element and returns true if the queue is full, returns false
PollRemove and return elements to the head of the queue if the queue is empty, NULL is returned
PeekReturns the element of the queue header returns null if the queue is empty
putAdd an element if the queue is full, block
TakeRemove and return elements of the queue header if the queue is empty, it blocks
Remove, element, offer, poll, peek are actually belong to the queue interface.
Blocking queues can be divided into three categories based on how they respond: The AAD, Removee, and element operations throw exceptions when you try to add elements to a full queue or to get elements from an empty queue. Of course, in multithreaded programs, the queue can become full or empty at any time, so you might want to use the offer, poll, peek method. These methods only give an error when the task cannot be completed and do not throw an exception.
Note: The poll and Peek methods fail in to return NULL. Therefore, inserting a null value into the queue is not legal.
There are also variants of offer and poll methods with timeouts, for example, the following call:
Boolean success = Q.offer (X,100,timeunit.milliseconds);
Attempts to insert an element into the tail of the queue within 100 milliseconds. If successful, returns true immediately; otherwise, when the timeout is reached, the return is false. Similarly, call:
Object head = Q.poll (timeunit.milliseconds);
If the queue header element has been successfully removed within 100 milliseconds, the element is immediately returned, otherwise null will return when the timeout is reached.
Finally, we have blocking operations put and take. The Put method blocks when the queue is full, and the take method blocks when the queue is empty.
The Java.ulil.concurrent package provides 4 variants of a blocking queue. By default, the capacity of theLinkedblockingqueue is unlimited (said inaccurate, when not specified when the capacity is integer.max_value, do not say how can be blocked when put), but you can also choose to specify its maximum capacity, It is a list-based queue, which sorts elements in FIFO (first-in-one-out).
arrayblockingqueue need to specify the capacity at the time of construction, and can choose whether to need fairness, if the fairness parameter is set to True, the longest waiting thread will be processed first (in fact, by setting Reentrantlock to True to This fairness is achieved: the thread that waits for the longest time is the first to operate. In general, fairness makes you pay for performance, and you can use it only when you really need it. It is an array-based blocking loop queue, which sorts elements by FIFO (first in, out) principle.
The priorityblockingqueue is a queue with priority, not a FIFO queue. elements are removed in order of priority, and there is no upper limit for the queue (look at the source code, Priorityblockingqueue is the re-packaging of Priorityqueue, is based on the heap data structure, and priorityqueue is no capacity limit, As with ArrayList, the put on the priority block queue is not blocked. Although this queue is logically unbounded, the attempt to perform an add operation may result in a outofmemoryerror if the resource is exhausted, but if the queue is empty, then the operation take of the element is blocked, so its retrieval operation takes is blocked. In addition, the elements that go into the queue are more capable.
Finally,Delayqueue(based on Priorityqueue) is an unbounded blocking queue that holds delayed elements that can be extracted only from the expiration of the delay. The head of the queue is the Delayed element with the longest save time after the delay expires. If the delay has not expired, the queue does not have a header, and poll returns NULL. When an element's Getdelay (Timeunit.nanoseconds) method returns a value less than or equal to zero, the expiration occurs, and poll removes the element. This queue does not allow the use of NULL elements. Here is the delay interface:
Java code
- Public interface Delayed extends comparable {
- Long Getdelay (timeunit unit);
- }
The elements put into delayqueue will also implement the CompareTo method, Delayqueue Use this to sort the elements.
The following example shows how to use a blocking queue to control the set of threads. The program searches all files in a directory and all its subdirectories, and prints a list of files containing the specified keywords. As can be seen from the following example, the use of blocking queues two significant advantages: multi-threaded operation of the common queue does not require additional synchronization, in addition, the queue will automatically balance the load, that is, the other side (production and consumption on both sides) processing faster will be blocked, thereby reducing the processing speed gap on both sides. Here are the specific implementations:
Java code
- public class Blockingqueuetest {
- public static void Main (string[] args) {
- Scanner in = new Scanner (system.in);
- System.out.print ("Enter base directory (e.g./usr/local/jdk5.0/src):");
- String directory = In.nextline ();
- System.out.print ("Enter keyword (e.g. volatile):");
- String keyword = in.nextline ();
- Final int file_queue_size = 10;//block Queue size
- Final int search_threads = 100;//keyword search thread count
- Arrayblockingqueue-based blocking queues
- Blockingqueue queue = new Arrayblockingqueue (
- File_queue_size);
- Start only one thread to search the directory
- Fileenumerationtask enumerator = new Fileenumerationtask (queue,
- New File (directory));
- New Thread (Enumerator). Start ();
- Start 100 threads to search for a specified keyword in a file
- for (int i = 1; I <= search_threads; i++)
- New Thread (New Searchtask (queue, keyword)). Start ();
- }
- }
- Class Fileenumerationtask implements Runnable {
- Dummy file object, placed at the end of the blocking queue, to indicate that the file has been traversed
- public static File DUMMY = new file ("");
- Private Blockingqueue queue;
- Private File startingdirectory;
- Public Fileenumerationtask (blockingqueue queue, File startingdirectory) {
- This.queue = queue;
- This.startingdirectory = startingdirectory;
- }
- public void Run () {
- try {
- Enumerate (startingdirectory);
- Queue.put (DUMMY);//execute here to indicate that the file under the specified directory has been traversed
- } catch (Interruptedexception e) {
- }
- }
- Places all files under the specified directory into a blocking queue as a file object
- public void Enumerate (File directory) throws Interruptedexception {
- file[] files = directory.listfiles ();
- for (File file:files) {
- if (File.isdirectory ())
- Enumerate (file);
- Else
- Put elements in the end of the queue and block if the queues are full
- Queue.put (file);
- }
- }
- }
- Class Searchtask implements Runnable {
- Private Blockingqueue queue;
- Private String keyword;
- Public Searchtask (blockingqueue queue, String keyword) {
- This.queue = queue;
- This.keyword = keyword;
- }
- public void Run () {
- try {
- Boolean done = false;
- while (!done) {
- Remove the first element of the queue and block if it is empty
- File File = Queue.take ();
- if (file = = Fileenumerationtask.dummy) {
- Take it out and put it back in so that other threads can read it and end it quickly.
- Queue.put (file);
- Done = true;
- } else
- Search (file);
- }
- } catch (IOException e) {
- E.printstacktrace ();
- } catch (Interruptedexception e) {
- }
- }
- public void Search (file file) throws IOException {
- Scanner in = new Scanner (new FileInputStream (file));
- int linenumber = 0;
- while (In.hasnextline ()) {
- linenumber++;
- String line = In.nextline ();
- if (line.contains (keyword))
- System.out.printf ("%s:%d:%s%n", File.getpath (), linenumber,
- line);
- }
- In.close ();
- }
- }
reprinted from: Http://www.cnblogs.com/end/archive/2012/10/25/2738493.html
Using Queues in Java: Java.util.Queue (GO)