Java thread (13): BlockingQueue-thread blocking queue

Source: Internet
Author: User
Tags addall

As a thread container, BlockingQueue can provide powerful guarantee for thread synchronization. The main methods used include:
[Java]
Add (E o); // add the specified element to this queue (if feasible immediately). true is returned upon success. In other cases, IllegalStateException is thrown.
DrainTo (Collection <? Super E> c); // remove all available elements from the queue and add them to the given collection.
DrainTo (Collection <? Super E> c, int maxElements); // removes a specified number of available elements from the queue and adds these elements to the given collection.
Offer (E o); // Insert the specified element into the queue if possible.
Offer (E o, long timeout, TimeUnit unit); // inserts the specified element into this queue. If there is no available space, it waits for the specified wait time (if necessary ).
Poll (long timeout, TimeUnit unit); // retrieves and removes the header of this queue. If there is no element in this queue, wait for the specified waiting time (if necessary ).
Put (E o); // Add the specified element to this queue. If there is no available space, it will wait (if necessary ).
RemainingCapacity (); // returns the number of elements that can be accepted by the queue without blocking (memory or resource constraints do not exist); if there is no internal limit, Integer. MAX_VALUE is returned.
Take (); // retrieves and removes the header of this queue. If this queue does not have any elements, it waits.

The put () and take () methods are mainly used in the preceding method. Only these two methods have the blocking wait function. In addition, BlockingQueue does not accept the null element. When you try to add, put, or offer a null element, some implementations will throw NullPointerException. Null is used as a warning value to indicate that the poll operation fails.
BlockingQueue can be defined as a capacity-limited queue, which has a remainingCapacity capacity value. Beyond this capacity, you cannot put additional elements without interruption. It can also be defined as a queue without capacity restrictions. BlockingQueue without capacity constraints always reports the remaining capacity of Integer. MAX_VALUE.
BlockingQueue implementation is thread-safe. All queuing methods can be automatically achieved using internal locking or other forms of concurrency control. However, a large number of Collection operations (addAll, containsAll, retainAll, and removeAll) do not require automatic execution unless otherwise specified in the implementation. Therefore, for example, after only some elements in c are added, addAll (c) may fail (throwing an exception ). In essence, it does not support any "close" or "shutdown" operation to indicate that no items are added. The demand and use of such features are dependent on implementation. For example, a common policy is to insert a special end-of-stream or poison object to the producer and explain the Objects Based on the time the user obtains them.
BlockingQueue is mainly used to implement producer-user queues, but it also supports the Collection interface. Therefore, for example, it is possible to remove any element from the queue using remove (x. However, such operations are generally not executed effectively and can only be used occasionally in a planned manner, for example, when queuing information is canceled. The blocked queue is very similar to Semaphore, but there are also many differences. The blocked queue generally stores data on one side and releases data on the other side, while Semaphore usually obtains and releases signals from the same side. The following is an example:
[Java]
Public class BlockingQueueTest {
Public static void main (String [] args ){
Final BlockingQueue queue = new ArrayBlockingQueue (3 );
For (int I = 0; I <2; I ++ ){
New Thread (){
Public void run (){
While (true ){
Try {
Thread. sleep (long) (Math. random () * 1000 ));
System. out. println (Thread. currentThread (). getName () + "prepare to put data! ");
Queue. put (1 );
System. out. println (Thread. currentThread (). getName () + "already put data," + "queue currently has" + queue. size () + "data ");
} Catch (InterruptedException e ){
E. printStackTrace ();
}
}
}

}. Start ();
}
New Thread (){
Public void run (){
While (true ){
Try {
// Change the sleep time here to 100 and 1000 respectively, and observe the running results.
Thread. sleep (1000 );
System. out. println (Thread. currentThread (). getName () + "Get Data! ");
Queue. take ();
System. out. println (Thread. currentThread (). getName () + "data has been taken away," +
"The queue currently has" + queue. size () + "data ");
} Catch (InterruptedException e ){
E. printStackTrace ();
}
}
}
}. Start ();
}
}

In the preceding example, we define a BlockingQueue that can store up to three data items, and create two threads for put () and one for take, this makes it easier for a blocking queue to form a full queue. When there are three data in the queue, two put () threads will wait, only when take () the thread can continue to add data to the queue only when a data is taken away. The running result is as follows (only partial results are removed ):
[Java]
Thread-1: Prepare to put data!
Thread-1 has data, and the queue currently has 1 Data
Thread-1: Prepare to put data!
Thread-1 has data, and the queue currently has 2 Data
Thread-0: Prepare to put data!
Thread-0 has data, and the queue currently has 3 data
Thread-0: Prepare to put data!
Thread-2 prepare to fetch data!
Thread-2 has taken data, and the queue currently has 2 Data

Since blocking queues can implement waiting between threads, we can implement thread synchronization through two blocking Queues with one space. The key code is as follows:
[Java]
BlockingQueue <Integer> queue1 = new ArrayBlockingQueue <Integer> (1 );
BlockingQueue <Integer> queue2 = new ArrayBlockingQueue <Integer> (1 );
Public void sub (int I ){
Try {
Queue1.put (1 );
} Catch (InterruptedException e ){
E. printStackTrace ();
}
For (int j = 1; j <= 10; j ++ ){
System. out. println ("sub thread sequece of" + j + ", loop of" + I );
}
Try {
Queue2.take ();
} Catch (InterruptedException e ){
// TODO Auto-generated catch block
E. printStackTrace ();
}
}
Public void main (int I ){
Try {
Queue2.put (1 );
} Catch (InterruptedException e1 ){
// TODO Auto-generated catch block
E1.printStackTrace ();
}
For (int j = 1; j <= 100; j ++ ){
System. out. println ("main thread sequece of" + j + ", loop of" + I );
}
Try {
Queue1.take (); www.2cto.com
} Catch (InterruptedException e ){
// TODO Auto-generated catch block
E. printStackTrace ();
}
}

In the preceding example, two methods are defined, one sub () and one main (). The two methods must be synchronized. Because the two blocking queues are defined with a capacity of 1, so as long as there is a queue1.put (1); then the sub () method must wait, and the sub () method can continue only when queue1.take () is in the main () method, the main () method is similar.

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.