Java multi-thread Series 6-blocking queue, java multi-thread 6-queue

Source: Internet
Author: User

Java multi-thread Series 6-blocking queue, java multi-thread 6-queue

This article uses the classic producer consumer example to further consolidate java multi-thread communication and introduces how to use blocking queues to simplify programs.

The following is an example of a classic producer consumer:

If the buffer is used to store integers, the buffer size is limited. The buffer provides the write (int) method to add an integer to the buffer. The read () method also reads and deletes an integer from the buffer. For synchronization operations, use the locks with two conditions, notEmpty (the buffer is not empty) and notFull (the buffer is not full ). When a buffer is added to a task, if the buffer is full, the task will wait for the notFull status. If the task deletes an int from the buffer, if the buffer is empty, the task waits for the notEmpty status.

Import java. util. using list; import java. util. concurrent. executorService; import java. util. concurrent. executors; import java. util. concurrent. locks. condition; import java. util. concurrent. locks. lock; import java. util. concurrent. locks. reentrantLock; public class ConsumerProducer {private static Buffer buffer = new Buffer (); public static void main (String [] args) {// create a thread pool ExecutorService executor = Executors. newFixedThreadPool (2); executor.exe cute (new Producertask (); executor.exe cute (new Consumertask (); executor. shutdown ();} private static class Producertask implements Runnable {@ Override public void run () {try {int I = 1; while (true) {System. out. println ("Producer writes" + I); buffer. write (I ++); Thread. sleep (int) (Math. random () * 10000);} catch (InterruptedException e) {e. printStackTrace () ;}} private static class Consumertask implements Runnable {public void run () {try {while (true) {System. out. println ("\ t \ tConsumer reads" + buffer. read (); Thread. sleep (int) (Math. random () * 10000);} catch (InterruptedException e) {e. printStackTrace () ;}} private static class Buffer {private static final int CAPACITY = 1; // buffer size shortlist <Integer> queue = new shortlist <Integer> (); // create the Lock private static lock = new ReentrantLock (); // create two conditions: private static Condition notEmpty = Lock. newCondition (); private static Condition notFull = lock. newCondition (); public void write (int value) {lock. lock (); // request lock try {while (queue. size () = CAPACITY) {System. out. println ("Wait for notFull condition"); notFull. await ();} queue. offer (value); notEmpty. signal (); // notEmpty condition signal} catch (Exception e) {e. printStackTrace ();} finally {lock. unlock (); // release lock }}@ SuppressWarnings ("finally") public int read () {int value = 0; lock. lock (); try {while (queue. isEmpty () {System. out. println ("\ t \ tWait for notEmpty condition"); notEmpty. await ();} value = queue. remove (); notFull. signal ();} catch (Exception e) {e. printStackTrace ();} finally {lock. unlock (); return value ;}}}}

Blocking queues

Blocking queues may cause thread blocking when attempting to add an element in a full queue or delete an element from an empty queue. The BlockQueue interface extends java. util. queue and provides synchronous put and take methods to add elements to the queue header and delete elements from the queue end.

Java supports three specific blocking Queues: ArrayBlockingQueue, LinkedblockingQueue, and PriorityBlockingQueue. They are all in the java. util. concurrent package.

ArrayBlockingQueue

A Bounded blocking queue supported by arrays. This queue sorts the elements according to the FIFO principle. QueueHeaderIs the element with the longest time in the queue. QueueTailIs an element with the shortest time in the queue. Insert the new element to the end of the queue. The queue acquisition operation obtains the element starting from the queue header.

This is a typical "bounded cache zone". fixed-size arrays keep the elements inserted by the producer and the elements extracted by the user. Once such a cache area is created, its capacity cannot be increased. Trying to forward to the full queuePutElement causes the operation to be blocked; an attempt is made to log on from an empty queue.ExtractElement causes similar blocking.

This class supports an optional fair policy for sorting the waiting producer thread and user thread. This sorting is not guaranteed by default. However, by setting fairnessTrueThe constructed queue allows access to threads in FIFO order. Fairness usually reduces throughput, but also reduces variability and avoids "imbalance ".

LinkedBlockingQueue

A blocking queue Based on a linked node with any range. This queue sorts elements by FIFO (first-in-first-out. QueueHeaderIs the longest element in the queue. QueueTailIs the minimum time element in the queue. The new element is inserted at the end of the queue, and the elements in the queue header are obtained after the queue get operation. The throughput of the link queue is usually higher than that of the array-Based Queue, but its predictable performance is lower in most concurrent applications.

Optional capacity range constructor parameters can be used to prevent queue overuse. If no capacity is specified, it is equalInteger.MAX_VALUE. Unless a node is inserted, the queue exceeds the capacity. Otherwise, a link node is dynamically created after each insertion.

PriorityBlockingQueue

An unbounded blocking queue, Which is used with the classPriorityQueueThe same order rules, and the blocking get operation is provided. Although this queue is logically unbounded, attempting to perform the add operation when resources are exhausted will also fail (resulting inOutOfMemoryError). This class is not allowedNullElement. Priority Queues that depend on natural order cannot insert non-comparable objects.ClassCastException).

The simplified code of using ArrayBlockingQueue is as follows:

Import java. util. concurrent. arrayBlockingQueue; import java. util. concurrent. executorService; import java. util. concurrent. executors; public class ConsumerProducerUsingBlockingQueue {private static ArrayBlockingQueue <Integer> buffer = new ArrayBlockingQueue <Integer> (2); public static void main (String [] args) {// create the thread pool ExecutorService executor = Executors. newFixedThreadPool (2); executor.exe cute (new Producertask (); executor.exe cute (new Consumertask (); executor. shutdown ();} private static class Producertask implements Runnable {@ Override public void run () {try {int I = 1; while (true) {System. out. println ("Producer writes" + I); buffer. put (I ++); Thread. sleep (int) (Math. random () * 10000);} catch (InterruptedException e) {e. printStackTrace () ;}} private static class Consumertask implements Runnable {public void run () {try {while (true) {System. out. println ("\ t \ tConsumer reads" + buffer. take (); Thread. sleep (int) (Math. random () * 10000);} catch (InterruptedException e) {e. printStackTrace ();}}}}

We can see that the code is halved, mainly because the ArrayBlockingQueue has been synchronized, so manual encoding is not required.

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.