Java multithreading 15:queue, Blockingqueue, and the use of Blockingqueue to implement producer/consumer models

Source: Internet
Author: User

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.


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.

/***/privatefinal  reentrantlock lock; /**  */privatefinal  Condition notempty; /**  */privatefinal Condition notfull;

4, Linkedblockingqueue

A linked list-based blocking queue, similar to Arrayblockingqueue. But linkedblockingqueue if you do not specify a queue size, it will default to a capacity that is like an infinite size, which is similar because the infinite size is integer.max_value, So it's good to understand why Arrayblockingqueue must be set size, if arrayblockingqueue do not specify the size of the integer.max_value, that will cause a lot of space waste, but based on the implementation of the list is not the same, A single node is 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*/Private FinalReentrantlock Takelock =NewReentrantlock ();/**Wait queue for waiting takes*/Private FinalCondition Notempty =takelock.newcondition ();/**Lock held by put, offer, etc*/Private FinalReentrantlock Putlock =NewReentrantlock ();/**Wait queue for waiting puts*/Private FinalCondition notfull = Putlock.newcondition ();

5, Synchronousqueue

Rather special, a waiting queue without buffering. What is called no buffer, arrayblocking is:

/** The queued Items   */ Private Final e[] items;

Arrays are used to store queues. The linkedblockingqueue include:

/***/staticclass node<e>    {/**   */    volatile  E item;    Node<E> next;     = 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:

 Public Static voidMain (string[] args) {FinalBlockingqueue<string> BQ =NewArrayblockingqueue<string> (10); Runnable producerrunnable=NewRunnable () {inti = 0;  Public voidrun () { while(true)            {                Try{System.out.println ("I produced a" + i++); Bq.put (i+ ""); Thread.Sleep (1000); }                 Catch(interruptedexception e) {e.printstacktrace ();    }            }        }    }; Runnable customerrunnable=NewRunnable () { Public voidrun () { while(true)            {                Try{System.out.println ("I have consumed a" +Bq.take ()); Thread.Sleep (3000); }                 Catch(interruptedexception e) {e.printstacktrace ();    }            }        }    }; Thread Producerthread=NewThread (producerrunnable); Thread Customerthread=NewThread (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:

1 I have produced a 02 I spent a 13 I have produced a 14 I have produced a 25 I spent a 26 I have produced a 37 I have produced a 48 I have produced a 59 I spent a 3Ten I have produced a 6 One I have produced a 7 A I have produced a 8 - I spent a 4 - I have produced a 9 the I have produced a ten - I have produced one - I spent a 5 - I have produced a + I have produced a - I have produced a + I spent a 6 A I have produced a at I have produced a - I spent a 7 - I have produced a - I spent a 8 -I have produced a 18

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

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: 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.