First, Blockingqueue interface
The Blockingqueue interface defines a blocked FIFO queue, each of which has a capacity to block when the data is added to the blockingqueue when the capacity is full blockingqueue The take element operation is blocked when the capacity is empty.
Second, Arrayblockingqueue
Arrayblockingqueue is a bounded blocking queue supported by an array . The entire container needs to be locked in both read and write operations, so the throughput is similar to the general implementation and is suitable for implementing the "producer consumer" model.
Third, Linkedblockingqueue
The Linkedblockingqueue maintains a data buffer queue (which consists of a list of lists), and when the producer puts a data into the queue, the queue fetches the data from the producer, caches it inside the queue, and the producer immediately returns Only when the queue buffer reaches the maximum cache capacity (Linkedblockingqueue can specify this value through the constructor), the producer queue is blocked until the consumer consumes a piece of data from the queue, and the producer thread is awakened, whereas the processing of the consumer side is based on the same principle. While Linkedblockingqueue is able to efficiently handle concurrency data, it also uses separate locks for both producer and consumer to control data synchronization, which means that producers and consumers can operate the data in the queue in parallel with high concurrency, This improves the concurrency performance of the entire queue.
The Linkedblockingqueue internally uses Reentrantlock to implement the Insert Lock (putlock) and the Remove lock (takelock). The condition variable on the Putlock is Notfull, which is the thread that can be woken up with notfull to block on the Putlock. The condition variable on the takelock is notemtpy, and you can wake up the thread that is blocking on the takelock with Notempty.
Iv. the difference between Arrayblockingqueue and Linkedblockingqueue
1. The implementation of locks in the queue is different
Arrayblockingqueue implemented in the queue of the lock is not separated, that is, production and consumption is the same lock;
Linkedblockingqueue implementation of the lock in the queue is separate, that is, production is putlock, consumption is takelock;
2. Different operation during production or consumption
Arrayblockingqueue is based on an array, when it is produced and consumed, it is inserted or removed directly from the enumeration object without generating or destroying any additional object instances;
Linkedblockingqueue is based on a linked list, when production and consumption, the need to convert the enumeration object to node<e> for insertion or removal, will generate an additional node object, which in a long period of time requires efficient and concurrent processing of large quantities of data in the system, There are some differences in the effect of GC;
3. The queue size is initialized differently
Arrayblockingqueue is bounded, the size of the queue must be specified;
The Linkedblockingqueue is unbounded and can not specify the size of the queue, but the default is Integer.max_value. Of course, the queue size can also be specified, thus becoming bounded;
Attention:
1. When using the Linkedblockingqueue, if the default size and when the production speed is greater than the consumption speed, there may be memory overflow;
2. When using Arrayblockingqueue and Linkedblockingqueue to queue 1 million simple characters respectively,
Linkedblockingqueue consumption is about 10 times times the consumption of Arrayblockingqueue,
That is, Linkedblockingqueue consumes around 1500ms, while Arrayblockingqueue only about 150ms.
Performance testing: Unlimited capacity of Linkedblockingqueue throughput > Arrayblockingqueue > Limited capacity Linkedblockingqueue
Arrayblockingqueue and Linkedblockingqueue Analysis