BlockingQueue Interface in Java
BlockingQueue is part of the java.util.concurrent package and extends the Queue interface. It represents a thread-safe queue that supports operations that wait for the queue to become non-empty when retrieving an element, and wait for space to become available when storing an element.
- Thread Safe: BlockingQueue implementations are thread-safe, with all methods being atomic.
- Blocking Operation: Has blocking behavior if the queue is full (for producers) or empty (for consumers).
- No Null Elements: Attempts to insert a null will result in a NullPointerException.
Declaration
public interface BlockingQueue<E> extends Queue<E>
Here, E is the type of elements stored in the Collection.
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class GFG{
public static void main(String[] args) throws InterruptedException{
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(3);
// Add elements
queue.put(1);
queue.put(2);
queue.put(3);
System.out.println("BlockingQueue: " + queue);
}
}
Output
BlockingQueue: [1, 2, 3]
The Hierarchy of BlockingQueue
It extends the Queue interface and provides implementations like LinkedBlockingQueue and ArrayBlockingQueue.

Classes that Implement BlockingQueue
- LinkedBlockingQueue: An optionally bounded blocking queue backed by linked nodes, usually with higher throughput than ArrayBlockingQueue.
- ArrayBlockingQueue: A bounded blocking queue backed by an array that stores elements in FIFO order.
Types of BlockingQueue
There are two types of BlockingQueue.
1. Unbounded Queue
Unbounded Queue is a queue that has no fixed capacity limit, allowing elements to be added indefinitely until system memory is exhausted.
BlockingQueue blockingQueue = new LinkedBlockingDeque();
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
public class GFG{
public static void main(String[] args) throws InterruptedException{
BlockingQueue<Integer> queue = new LinkedBlockingDeque<>();
// Adding elements
queue.put(10);
queue.put(20);
queue.put(30);
System.out.println("Unbounded Queue: " + queue);
}
}
Output
Unbounded Queue: [10, 20, 30]
2. Bounded Queue
Bounded Queue is a queue with a fixed capacity that limits the number of elements it can hold at a time.
BlockingQueue blockingQueue = new LinkedBlockingDeque(5);
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
public class GFG{
public static void main(String[] args) throws InterruptedException{
BlockingQueue<Integer> queue = new LinkedBlockingDeque<>(3);
// Adding elements
queue.put(1);
queue.put(2);
queue.put(3);
// queue.put(4); // This would block until space is available
System.out.println("Bounded Queue: " + queue);
}
}
Output
Bounded Queue: [1, 2, 3]
Basic Operations on BlockingQueue
1. Adding Elements
Elements can be added using add(), put(), or offer() methods.
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
public class GFG{
public static void main(String[] args){
BlockingQueue<Integer> bq = new LinkedBlockingDeque<>();
bq.add(78);
bq.add(35);
bq.add(52);
bq.add(74);
System.out.println("BlockingQueue: " + bq);
}
}
Output
BlockingQueue: [78, 35, 52, 74]
2. Accessing Elements
The elements of the LinkedBlockingDeque can be accessed using contains(), element(), peek(), poll().
import java.util.concurrent.*;
public class GFG{
public static void main(String[] args) {
BlockingQueue<Integer> queue = new LinkedBlockingDeque<>();
queue.add(22);
queue.add(125);
queue.add(723);
queue.add(172);
queue.add(100);
System.out.println("Queue: " + queue);
if (queue.contains(22))
System.out.println("Queue contains 22");
int head = queue.element();
System.out.println("Head of queue: " + head);
}
}
Output
Queue: [22, 125, 723, 172, 100] Queue contains 22 Head of queue: 22
3. Deleting Elements
Elements can be deleted from a LinkedBlockingDeque using remove(). Other methods such as take() and poll() can also be used in a way to remove the first and the last elements.
import java.util.concurrent.*;
public class GFG{
public static void main(String[] args){
BlockingQueue<Integer> queue = new LinkedBlockingDeque<>();
queue.add(75);
queue.add(86);
queue.add(13);
queue.add(44);
queue.add(10);
System.out.println("Before removing: " + queue);
queue.remove(86);
queue.remove(44);
queue.remove(1);
System.out.println("After removing: " + queue);
}
}
Output
Before removing: [75, 86, 13, 44, 10] After removing: [75, 13, 10]
4. Iterating through the Elements
We can use an iterator to traverse the queue.
import java.util.Iterator;
import java.util.concurrent.*;
public class GFG{
public static void main(String[] args){
BlockingQueue<Integer> queue = new LinkedBlockingDeque<>();
queue.add(166);
queue.add(246);
queue.add(66);
queue.add(292);
queue.add(98);
Iterator<Integer> iterator = queue.iterator();
System.out.println("BlockingQueue elements:");
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
}
}
Output
BlockingQueue elements: 166 246 66 292 98
Methods of BlockingQueue
| Method | Description |
|---|---|
| void put(E e) | Inserts the specified element, waiting if necessary for space to become available. |
| E take() | Retrieves and removes the head element, waiting if necessary until an element becomes available. |
| boolean offer(E e) | Inserts the specified element immediately, returning false if the queue is full. |
| boolean offer(E e, long timeout, TimeUnit unit) | Inserts the element, waiting up to the specified time for space. |
| E poll() | Retrieves and removes the head element immediately, or returns null if the queue is empty. |
| E poll(long timeout, TimeUnit unit) | Retrieves and removes the head element, waiting up to the specified time if empty. |
| E peek() | Retrieves, but does not remove, the head element, or returns null if empty. |
| boolean add(E e) | Inserts the specified element immediately, throwing an exception if the queue is full. |
| boolean remove(Object o) | Removes a specific element from the queue if present. |
| boolean contains(Object o) | Checks if the specified element exists in the queue. |
| int remainingCapacity() | Returns the number of additional elements the queue can accept without blocking. |
| boolean isEmpty() | Checks if the queue contains no elements. |
| Iterator<E> iterator() | Returns an iterator over the elements in the queue in proper sequence. |
| E element() | Retrieves, but does not remove, the head element; throws NoSuchElementException if empty. |