Blocking collections

Blocking collections have operations that block the current thread until the operation completes. There are also conditions for performing operations such as availability of free space. They are useful as a bridge between miltiple threads and a single thread, for example in producer/consumer pattern:

  • single thread produces events and the thread pool handles them
  • the thread pool produces events and single thread handles them

If you don't need those conditions, you can use synchronized collections.

If you want that threads access the collection independently and without blocking, use concurrent collections.

BlockingQueue

BlockingQueue provides additional methods for Queue interface, that block the current thread until the conditions are met.

Following are the main methods of the BlockingQueue interface.

method description
add(e) Inserts the specified element into this queue. Throws an IllegalStateException exception if no space is currently available.
put(e) Inserts the specified element into this queue, waiting if necessary for space to become available.
offer(e) Inserts the specified element into this queue. Returns true if the element was added to this queue, else false.
offer(e, time, timeUnit) Inserts the specified element into this queue, waiting up to the specified wait time if necessary for space to become available.
remove(obj) Removes a single instance of the specified element from this queue, if it is present. Returns true if this queue contained the specified element.
poll() Retrieves and removes the head of this queue.
poll(timeout, timeUnit) Retrieves and removes the head of this queue, waiting up to the specified wait time if necessary for an element to become available.
take() Retrieves and removes the head of this queue, waiting if necessary until an element becomes available.
peek() Retrieves, but does not remove, the head of this queue.
element() Retrieves, but does not remove, the head of this queue. This method differs from peek only in that it throws an exception if this queue is empty.

Some implementation classes are ArrayBlockingQueue, DelayQueue, LinkedBlockingQueue, LinkedTransferQueue, SynchronousQueue.

TransferQueue

Extensions of BlockingQueue in which producers may wait for consumers to receive elements.

A TransferQueue may be useful for example in message passing applications in which producers sometimes (using method transfer(E)) await receipt of elements by consumers invoking take or poll, while at other times enqueue elements (via method put) without waiting for receipt.

It has one known implementation - the LinkedTransferQueue class.

Following are the main methods of the TransferQueue interface.

method description
getWaitingConsumerCount() Returns an estimate of the number of consumers waiting to receive elements via BlockingQueue.take() or timed poll.
hasWaitingConsumer() Returns true if there is at least one consumer waiting to receive an element via BlockingQueue.take() or timed poll.
transfer(e) Transfers the element to a consumer, waiting if necessary to do so.
tryTransfer(e) Transfers the element to a waiting consumer immediately, if possible.
tryTransfer(e, timeout, timeUnit) Transfers the element to a consumer if it is possible to do so before the timeout elapses.

BlockingDeque

BlockingDeque provides additional methods for the Deque interface, that block the current thread until the conditions are met.

Following are the main methods of the BlockingDeque interface.

method description
putFirst(e) Inserts the specified element at the front of this deque, waiting if necessary for space to become available.
putLast(e) Inserts the specified element at the end of this deque, waiting if necessary for space to become available.
takeFirst(e) Retrieves and removes the first element of this deque, waiting if necessary until an element becomes available.
takeLast(e) Retrieves and removes the last element of this deque, waiting if necessary until an element becomes available.

ArrayBlockingQueue

This is implementation of BlockingQueue based on array.

Unlike LinkedBlockingQueue, once created, the capacity cannot be changed. Also it uses single-lock double condition algorithm, and LinkedBlockingQueue uses two locks, one for inserting and one for removing elements.

LinkedBlockingQueue

This is implementation of BlockingQueue based on linked nodes.

Unlike ArrayBlockingQueue, it can be of unbound size. Also it uses two locks, one for inserting and one for removing elements.

LinkedBlockingDeque

An optionally-bounded implementation of the BlockingDeque interface based on linked nodes.

PriorityBlockingQueue

An unbounded blocking queue that uses the same ordering rules as the PriorityQueue class and supplies blocking retrieval operations.

SynchronousQueue

A blocking queue in which each insert operation must wait for a corresponding remove operation by another thread, and vice versa.

It does not have any internal capacity, it acts as an empty collection. Therefore you cannot peek? element.

SynchronousQueue is well suited when an one object running on one thread must synchronize with an object running on another thread to pass some information, event, or task to it.

DelayQueue

DelayQueue is an unbounded blocking queue of Delayed elements, in which an element can only be taken when its delay has expired.