The java.util.concurrent.BlockingDeque
interface extends the Deque interface with additional blocking operations:
- Dequeue operations that, when taking an element from an empty deque, wait until an element is available (i.e., until another thread inserts one).
- Enqueue operations that, when an element is inserted into a full¹ deque, block until space is available again (i.e., until another thread has taken an element).
BlockingDeque
also extends BlockingQueue, and indirectly – via both Deque
and BlockingQueue
– the Queue
and Collection
interfaces:
¹ A deque is full when it is bounded, and the number of elements inserted into the deque has reached the specified deque capacity.
Java BlockingDeque Methods
The blocking methods are available in two variants: one that waits indefinitely and one that takes a timeout parameter. When this timeout expires, the method terminates and returns an error code.
The methods that BlockingDeque
inherits from BlockingQueue
(e.g., enqueue at the tail, dequeue at the head) have been additionally defined with new names for consistency – for example, BlockingQueue.put()
as BlockingDeque.putLast()
.
In the following listing of methods, I include these BlockingQueue
methods with the equivalent BlockingDeque
methods.
At the end of the chapter, two tables summarize all the methods.
Blocking Methods for Inserting into the Deque
First, a graphical representation of the blocking enqueue methods:
BlockingDeque.putFirst() + putLast()
The methods putFirst()
and putLast()
insert an element at the beginning and end of the deque, respectively, if space is available. If the deque is full, however, these methods block until another thread has taken an element and thus space is available again for the new element.
The put()
method inherited from the BlockingQueue
interface is forwarded to BlockingDeque.putLast()
.
BlockingQueue.offerFirst() + offerLast() with Timeout
Also, offerFirst()
and offerLast()
insert an element into the deque if space is available. Otherwise, these methods block for at most the specified time. If the element could not be inserted after this time, these methods return false
.
The offer(E e, long timeout, TimeUnit unit)
method inherited from the BlockingQueue
interface is forwarded to BlockingDeque.offerLast(E e, long timeout, TimeUnit unit)
.
Blocking Methods for Removing from the Deque
First, again, a graphical representation of the blocking dequeue methods:
BlockingQueue.takeFirst() + takeLast()
takeFirst()
and takeLast()
take an element from the beginning and end of the deque, respectively, if the deque is not empty. If the deque is empty, these methods block until another thread inserts an element.
The take()
method inherited from the BlockingQueue
interface is forwarded to BlockingDeque.takeFirst()
.
BlockingQueue.pollFirst() + pollLast() with Timeout
Also, pollFirst()
and pollLast()
take an element from the deque if one is available. Otherwise, the methods wait for the specified time. If an element is inserted within the wait time, the methods return it immediately. If there is still no element after the time expires, these methods return null
.
The poll(E e, long timeout, TimeUnit unit)
method inherited from the BlockingQueue
interface is forwarded to BlockingDeque.pollFirst(E e, long timeout, TimeUnit unit)
.
BlockingDeque Methods – Summary
Below you will find two tables: the first one contains the methods for inserting and removing elements at the head of the deque; the second one lists the methods for the elements at the tail of the deque.
In the first two columns, you can see the non-blocking methods BlockingDeque
inherits from Deque
(and indirectly from Queue
– marked with a superscript 1).
In the third and fourth columns, you will find the new blocking methods (including those defined in BlockingQueue
– marked with a superscript 2).
Operations at the Beginning (Head) of the Deque
Non-blocking (inherited from Deque ) | Blocking (new in BlockingDeque ) | |||
---|---|---|---|---|
Exception | Return value | Blocks | Blocks with timeout | |
Inserting an element (enqueue): | addFirst(E e) | offerFirst(E e) | putFirst(E e) | offerFirst(E e, |
Removing an element (dequeue): | removeFirst() ¹ | pollFirst() ¹ | takeFirst() ² | pollFirst( ² |
Viewing an element (examine): | getFirst() ¹ | peekFirst() ¹ | – | – |
Operations at the End (Tail) of the Deque
Non-blocking (inherited from Deque ) | Blocking (new in BlockingDeque ) | |||
---|---|---|---|---|
Exception | Return value | Blocks | Blocks with timeout | |
Inserting an element (enqueue): | addLast(E e) ¹ | offerLast(E e) ¹ | putLast(E e) ² | offerLast(E e, ² |
Removing an element (dequeue): | removeLast() | pollLast() | takeLast() | pollLast( |
Viewing an element (examine): | getLast() | peekLast() | – | – |
¹ These methods are implemented in the Queue
interface and call the corresponding Deque
methods.
² These methods are implemented in the BlockingQueue
interface and invoke the corresponding BlockingDeque
methods.
Java BlockingDeque Example
For an example of how to use the BlockingDeque
interface, check out the tutorial on the sole implementation of this interface: LinkedBlockingDeque.
Summary and Outlook
In this article, you learned about the BlockingDeque interface and its blocking methods putFirst()
, putLast()
, offerFirst()
, offerLast()
, takeFirst()
, takeLast()
, and pollFirst()
, pollLast()
.
In the following parts of this tutorial series, I will describe all Deque
and BlockingDeque
implementations with their specific characteristics. Afterward, you will find a recommendation on when to use which deque implementation. At the end of the tutorial, I will show you how to implement a Deque yourself.
If you still have questions, please ask them via the comment function. Do you want to be informed about new tutorials and articles? Then click here to sign up for the HappyCoders.eu newsletter.