Java multi-thread (9) blocking queue, java multi-thread blocking queue

Source: Internet
Author: User

Java multi-thread (9) blocking queue, java multi-thread blocking queue

Reprinted please indicate the source: http://blog.csdn.net/xingjiarong/article/details/48005091

In the previous blog, we introduced how to use Object locks, conditional locks, and more convenient synchronized keywords to implement multi-thread synchronization and mutual exclusion. You may think it is very convenient to use the synchronized keyword, however, users must really understand the usage of synchronized and have some experience in multi-threaded programming. Otherwise, it is difficult to fully consider the problem and cause unexpected problems. In fact, there is a more convenient way to achieve synchronization and mutex than the synchronized keyword in java, and there is no need to consider complicated issues, that is, the use of blocking queues, this time we will discuss the use of blocking queues.

For example, we often give an example-bank transfer. Every time we write this program, we have to consider a lot of issues, such as how the two threads should be mutually exclusive, what should we do if the amount is insufficient. In fact, we can solve this problem elegantly and securely through a queue. The transfer thread inserts the transfer instruction object into a queue, instead of directly accessing the bank object. Another thread extracts commands from the queue to execute the transfer. Because only the thread can access the internal methods of the Bank object, synchronization and mutex are not required.

Blocking queue means that when an attempt is made to add an element to the queue and the queue is full, or the queue is empty to remove an element from the queue, the thread that executes this operation will be blocked. When coordinating multiple threads, blocking the queue is a useful tool. The worker thread can periodically store intermediate results in the queue, other threads remove intermediate results and perform further processing. The queue performs Automatic Load Balancing. When the queue is full, threads that add elements to the queue will be blocked. When the queue is empty, the thread that tries to retrieve elements from the queue is blocked.

Java mainly has the following blocking Queues:

1. ArrayBlockingQueue

This queue is implemented using a cyclic array. There are two constructor methods:

1) blocked Queues with a specified capacity

ArrayBlockingQueue(int capacity)

2) blocked Queues with specified capacity and fairness settings

ArrayBlockingQueue(int capacity,boolean fair)

The thread with the longest wait time will be given priority when a fair blocking queue is awakened, but this does not guarantee absolute fairness, because a fair blocking queue will reduce the efficiency, so it is generally not used, by default, the queue is blocked fairly.

2. Define blockingqueue

This queue is implemented using a linked list. There are two constructor methods:

1) construct an uncapped blocking queue

LinkedBlockingQueue();

2) construct a blocking queue with an upper limit

LinkedBlockingQueue(int capacity);

3. Define blockingdeque

The construction method and implementation principle of this queue are both the same. The difference between the two is that the LinkedBlockingDeque is a two-way queue.

4. DelayQueue

Construct an unbounded blocking queue containing Delayed elements with limited blocking time. Only those elements with excessive latency can be removed from the queue.

Constructor:DelayQueue();

5. PriorityBlockingQueue

The queue is blocked by priority. The queue with a higher priority is removed from the queue first. There are three constructor methods for this queue to be implemented using heap:

PriorityBlockingQueue();PriorityBlockingQueue(int initialCapacity);PriorityBlockingQueue(int initialCapacity,Comparator<? super E> compaator);

InitialCapacity: initial capacity of the priority queue. The default value is 11.
Comparator is used to compare elements. If not specified, the Comparable interface must be implemented for the elements.

Common Methods for blocking queues

Method Normal action Actions in special circumstances
Add Add an element If the queue is full, an IllegalStateException is thrown.
Remove Remove and return the Header element If the queue is empty, a NoSuchElementException exception is thrown.
Put Add an element Blocking if the queue is full
Take Remove and return the Header element If the queue is empty, it is blocked.
Peek Return the Header element of the queue. If the queue is empty, null is returned.
Poll Removes and returns the Header element of the queue. If the queue is empty, null is returned.
Element Return the Header element of the queue. If the queue is empty, a NoSuchElementException exception is thrown.
Offer Add an element and return true If the queue is full, false is returned.

The following describes how to use a blocking queue to implement producer consumer problems:

The producer and consumer problem is a typical thread synchronization problem. Producers and consumers share a buffer zone and can be seen as warehouses. Producers and production products are placed in warehouses, and consumers take products from warehouses for consumption, when the Warehouse is empty, the consumer is blocked. When the Warehouse is full, the producer is blocked.

Import java. util. concurrent. arrayBlockingQueue; public class ProductThread implements Runnable {private ArrayBlockingQueue <Integer> queue; public ProductThread (ArrayBlockingQueue <Integer> queue) {this. queue = queue;} public void run () {while (true) {try {int product = (int) (Math. random () * 10);/** when the queue is full, it will block */queue. put (product); System. out. println (Thread. currentThread () + "produced product --" + product + "remaining element:" + queue. size (); Thread. sleep (1000);} catch (Exception e) {e. printStackTrace ();}}}}
Import java. util. concurrent. arrayBlockingQueue; public class ConsumeThread implements Runnable {private ArrayBlockingQueue <Integer> queue; public ConsumeThread (ArrayBlockingQueue <Integer> queue) {this. queue = queue;} public void run () {while (true) {try {/** when the queue is empty, */int product = queue. take (); System. out. println (Thread. currentThread () + "consumed element --" + product + "available space:" + queue. size (); Thread. sleep (1000);} catch (Exception e) {e. printStackTrace ();}}}}
Import java. util. concurrent. arrayBlockingQueue; public class Main {public static void main (String [] args) {// The circular array with a size of 10 blocks the queue ArrayBlockingQueue <Integer> queue = new ArrayBlockingQueue <> (10 ); /** use five producer threads to produce products */for (int I = 0; I <5; I ++) {new Thread (new ProductThread (queue )). start ();}/** use two consumer threads to consume the product */for (int I = 0; I <2; I ++) {new Thread (new ConsumeThread (queue )). start ();}}}

Running result:

Thread [Thread-2, 5, main] produces the product-4 residual elements: 4
Thread [Thread-5, 5, main] consumes elements -- 1 space remaining: 3
Thread [Thread-1, 5, main] produces the product -- 1 residual element: 3
Thread [Thread-6, 5, main] consumes elements -- 1 space remaining: 3
Thread [Thread-0, 5, main] produces the product-0 residual elements: 3
Thread [Thread-4, 5, main] produces the product -- 1 residual element: 3
Thread [Thread-3, 5, main] produces the product-9 remaining elements: 4
Thread [Thread-0, 5, main] produces the product -- 2 remaining elements: 5
Thread [Thread-1, 5, main] produces the product-9 remaining elements: 5
Thread [Thread-4, 5, main] produces the product-6 remaining elements: 7
Thread [Thread-2, 5, main] produces the product -- 2 remaining elements: 7
Thread [Thread-3, 5, main] produces the product -- 1 residual element: 7
Thread [Thread-5, 5, main] consumes elements -- 4 available space: 6
Thread [Thread-6, 5, main] consumes the element -- 0 remaining space: 7
Thread [Thread-0, 5, main] produces the product-0 residual elements: 7
Thread [Thread-4, 5, main] produces the product-7 remaining elements: 8
Thread [Thread-3, 5, main] produces the product-5 remaining elements: 9
Thread [Thread-1, 5, main] produces the product-4 remaining elements: 10
Thread [Thread-5, 5, main] consumes elements -- 9 available space: 9
Thread [Thread-2, 5, main] produces the product -- 9 remaining elements: 10
Thread [Thread-6, 5, main] consumes elements -- 2 remaining space: 9
Thread [Thread-1, 5, main] produces the product-4 remaining elements: 10
Thread [Thread-0, 5, main] produces the product -- 3 remaining elements: 10
Thread [Thread-6, 5, main] consumes elements -- 2 remaining space: 9
Thread [Thread-4, 5, main] produces the product-5 remaining elements: 10
Thread [Thread-5, 5, main] consumes elements -- 9 remaining space: 10
Thread [Thread-3, 5, main] produces the product -- 9 remaining elements: 10
Thread [Thread-5, 5, main] consumes elements-6 remaining space: 10
Thread [Thread-6, 5, main] consumes elements -- 1 space remaining: 10
Thread [Thread-2, 5, main] produces the product -- 2 remaining elements: 10
Thread [Thread-0, 5, main] produces the product -- 1 residual element: 10
Thread [Thread-5, 5, main] consumes the element -- 0 remaining space: 10
Thread [Thread-4, 5, main] produces the product-4 remaining elements: 10
Thread [Thread-6, 5, main] consumes elements -- 7 remaining space: 10
Thread [Thread-5, 5, main] consumes elements-5 remaining space: 10

From the results, we can see that the blocking queue is empty at the beginning, and multiple production threads are produced at the same time. When there is a product, two consumers start to consume it because there are a large number of producers, so the queue is gradually filled up. When the queue is full, the producer thread is congested and can only wait for the consumer to consume a product before reproduction. Therefore, the result of consuming a product and producing a product is finally displayed.

Source code download: http://download.csdn.net/detail/xingjiarong/9052057

Copyright Disclaimer: This article is the original author article, reprint please indicate the source, view the original article, please visit: http://blog.csdn.net/xingjiarong

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.