Blocking queue in java

Phoenix Rivers
3 min readJul 4, 2024

--

A BlockingQueue in Java is a type of queue that supports operations that wait for the queue to become non-empty when retrieving an element, and wait for space to become available in the queue when storing an element. It’s a key component in concurrent programming, facilitating safe communication and coordination between threads by providing blocking operations that handle contention and synchronization automatically.

Image Source

Key Features:

  1. Thread-Safe Operations: BlockingQueue implementations ensure that multiple threads can safely access and modify the queue concurrently without the risk of data corruption or inconsistency.
  2. Blocking Operations: BlockingQueue offers methods that block the calling thread until certain conditions are met:
  • put(E e): Inserts the specified element into the queue if space is available, waits indefinitely otherwise.
  • take(): Retrieves and removes the head of the queue, waits indefinitely until an element becomes available.
  • offer(E e, long timeout, TimeUnit unit): Inserts the specified element into the queue, waits up to the specified timeout if necessary.
  • poll(long timeout, TimeUnit unit): Retrieves and removes the head of the queue, waits up to the specified timeout if necessary.

3. Fairness: Some implementations of BlockingQueue support fairness policies, where threads are granted access in the order they requested it, preventing indefinite blocking of certain threads in favor of others.

4. Ordering: Elements are typically stored and retrieved in FIFO (First-In-First-Out) order, unless a different ordering mechanism is specified.

5. Bounded and Unbounded: BlockingQueue can be bounded (fixed capacity) or unbounded (no fixed capacity), depending on the implementation chosen.

Example Usage with ArrayBlockingQueue:

Here’s an example using ArrayBlockingQueue, a bounded blocking queue backed by an array for solving producer consumer problem:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueExample {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(5); // Creates a blocking queue with capacity 5

// Producer thread
Thread producer = new Thread(() -> {
try {
for (int i = 1; i <= 10; i++) {
queue.put(i); // Puts elements into the queue, waits if full
System.out.println("Produced: " + i);
Thread.sleep(1000); // Simulate some time taken to produce
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});

// Consumer thread
Thread consumer = new Thread(() -> {
try {
for (int i = 1; i <= 10; i++) {
int value = queue.take(); // Retrieves and removes elements from the queue, waits if empty
System.out.println("Consumed: " + value);
Thread.sleep(2000); // Simulate some time taken to consume
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});

// Start producer and consumer threads
producer.start();
consumer.start();

// Wait for threads to complete
producer.join();
consumer.join();

System.out.println("Finished");
}
}

Use Cases:

  • Producer-Consumer Pattern: Efficiently manage data flow between threads where one or more threads produce data and one or more threads consume that data.
  • Task Synchronization: Coordinate and synchronize tasks in a multithreaded environment, ensuring orderly execution and resource management.
  • Bounded Resource Management: Manage access to limited resources such as thread pools, connections, or shared data structures.

Conclusion:

BlockingQueue is a fundamental tool in Java’s java.util.concurrent package, providing robust support for concurrent programming by handling synchronization and blocking operations transparently. It simplifies the implementation of thread-safe communication and coordination patterns, making it easier to develop efficient and scalable multithreaded applications in Java.

--

--