What is a queue?
Queue, is a data structure. In addition to the priority queue and the LIFO queue, the queues are sorted in FIFO (first-in, in-place) order for each element. The header of the queue is called remove () or poll () to remove the element, regardless of the sort method used. In the FIFO queue, all new elements are inserted at the end of the queue.
Methods in the queue
The method in the queue is not difficult to understand, 6, every 2 pairs is a total of 3 pairs. Look at the JDK API and you'll know:
It's good to note that thequeue usually does not allow null insertion, although some implementations (such as LinkedList) are allowed, but are not recommended.
Blockingqueue
1. Blockingqueue Overview
Speak only Blockingqueue, because Blockingqueue is a priority in the queue, and through blockingqueue we deepen our understanding of the producer/consumer model again. The rest of the queue is easy, and you can understand their role by looking at the JDK API and simply reading the source code.
Blockingqueue, as the name implies, blocks the queue . Blockingqueue is under the java.util.concurrent, so it is not difficult to understand, Blockingqueue is to solve multi-threading data efficient and secure transmission of the proposed.
Multi-threading, many scenarios can be implemented using queues, such as the classic producer/consumer model, through the queue can easily realize the sharing of data between the two, define a producer thread, define a consumer thread, through the queue to share data.
Of course, the reality can not be ideal, such as consumer consumption faster than producer production speed, then consumer consumption to a certain extent, must be suspended waiting for a bit (so that the consumer thread in the waiting state). Blockingqueue to solve this problem, he does not need programmers to control the details, but also to take into account efficiency and thread safety.
Blocking queues are so-called "blocking", which means that in some cases the thread hangs (or blocks), and once the condition is met, the suspended threads wake up automatically . With Blockingqueue, you don't need to worry about when you need to block threads and when you need to wake them up, the content blockingqueue is ready.
2, the method in Blockingqueue
Blockingqueue since it is the sub-interface of the queue, there must be a method in the queue, which is listed above. Take a look at the unique methods in Blockingqueue:
(1) void put (E e) throws Interruptedexception
Add e into the blockingqueue, if there is no space in the Blockingqueue, the calling thread is blocked and waits until there is space in the blockingqueue to continue
(2) void Take () throws Interruptedexception
Take the Blockingqueue inside the first object, if the Blockingqueue is empty, then the calling thread is blocked, into the wait state until blockingqueue new data is added
(3) int drainto (COLLECTION<? super e> C, int maxelements)
Once you have taken the data from the Blockingqueue to C, you can specify the number of takes. This method improves the efficiency of data acquisition and does not require multiple locks or release of locks in batches.
3, Arrayblockingqueue
You must specify the queue size . relatively simple. There is only one Reentrantlock object in Arrayblockingqueue, which means that producers and consumers cannot run in parallel (see code below). In addition, when you create a arrayblockingqueue, you can specify whether Reentrantlock is a fair lock and the default is a non-fair lock.
/***/final reentrantlock lock; /***/final Condition notempty; /***/final Condition notfull;
4, Linkedblockingqueue
A linked list-based blocking queue, similar to Arrayblockingqueue. However linkedblockingqueue if you do not specify a queue capacity size, it will default to a similar unlimited size capacity, the reason is similar because this infinite size is integer.max_value, so that is good understanding arrayblockingqueue Why must make size, if Arrayblockingqueue not specify the size of the words with integer.max_value, that will cause a lot of space waste, but based on the implementation of the list is not the same, a node connected together. In addition, linkedblockingqueue producers and consumers have their own locks (see code below), which means that producers and consumers can run "simultaneously".
/**Lock held by Take, poll, etc*/PrivateFinal Reentrantlock Takelock =New Reentrantlock (); /** Wait queue for waiting takes */private final Condition notempty = Takelock.newcondition (); /** Lock held by put, offer, etc */private final reentrantlock putlock = new Reentrantlock (); */private final Condition notfull = putlock.newcondition ();
5, Synchronousqueue
Rather special, a waiting queue without buffering. What is called no buffer, arrayblocking is:
/** the queued items */final e[] items;
Arrays are used to store queues. The linkedblockingqueue include:
/***/class node<e>/**volatile E item; Node<e> Next; Node (E x) {item = x;}}
Connect the queue as a linked list.
Producer/consumer operations data are actually manipulating the data through these two "intermediaries", but the Synchronousqueue is that the producer directly gives the data to the consumer (the consumer takes the data directly from the producer), as if returning to the old way of not having a producer/consumer model. In other words, Each insert operation must wait for a thread to remove the corresponding action . Synchronousqueue has two different modes:
1. Fair mode
Use a fair lock and work with a FIFO queue to manage excess producers and consumers
2. Non-equity mode
With an unfair lock and with a LIFO stack (stack) to manage excess producers and consumers, this is also the Synchronousqueue default mode
Using Blockingqueue to realize producer consumer model
The previous article we wrote about the producer consumer model has limitations, which are embodied in:
1, the buffer can only hold one data, the actual producer/consumer model in the buffer area can be stored in a large number of producers produced data
2. Producers and consumers process data almost as fast
OK, let's use Blockingqueue to write a simple example, and let the producer, consumer processing data speed is different. The subclass chooses Arrayblockingqueue, and the size is set at 10:
PublicStaticvoidMain (string[] args) {Final blockingqueue<string> BQ =New Arrayblockingqueue<string> (10); Runnable producerrunnable =NewRunnable () {int i = 0;PublicvoidRun () {while (True) {Try{System.out.println ("I produced a" + i++); Bq.put (i + "")); Thread.Sleep (1000); }Catch(Interruptedexception e) {E.printstacktrace ();} } } }; Runnable customerrunnable =New Runnable () {public Void run () {while (true try Bq.take ()); Thread.Sleep (3000catch (Interruptedexception e) {e.printstacktrace ();}}} }; Thread producerthread = new thread (producerrunnable); Thread customerthread = new thread (customerrunnable); Producerthread.start (); Customerthread.start ();}
The code is to allow producers to produce faster than consumer consumption, and look at the results of the operation:
1I have produced a 02I spent a 13I have produced a 14I have produced a 25I spent a 26I have produced a 37I have produced a 48I have produced a 59I spent a 310I have produced a 611I have produced a 712I have produced a 813I spent a 414I have produced a 915I have produced a 1016 I produced a 1117 I consumed a 518 I produced a 1219 I produced a 1320 I produced a 14< Span style= "color: #008080;" >21 I consumed a 622 I produced a 15 23 I produced a 1624 I consumed a 725 I produced a 1726 I consumed a 827 I produced a.
The output is shown in two parts:
1, line 1th ~ Line 23rd. This piece of blockingqueue is not full, so the producers casually production, consumers casually consumption, basically is the production of 3 consumption 1, consumer consumption rate is slow
2, line 24th ~ 27th line, from the front we can see, production to 16, consumption to 6, explained to the Arrayblockingqueue limit 10, at this time no way, the producer produces a arrayblockingqueue is full, so can not continue to produce, It is only when consumers have finished spending that they can continue to produce. So after the print content must be a producer, a consumer
This is the "speed at which the overall processing of data can be improved by balancing the processing power of producers and consumers ", as stated in the previous chapter, which should be evident in the example. In addition, do not worry about the non-single producer/consumer scene of the system animation problem, buffer empty, buffer full scene blockingqueue are defined by different condition, so will not wake up their own kind.
Java multithreading 15:queue, Blockingqueue, and the use of Blockingqueue to implement producer/consumer models