Blocking Queues and ConcurrentLinkedQueue

Welcome to Blocking Queues and ConcurrentLinkedQueue

Building upon your skills with synchronized and concurrent collections, this lesson explores Blocking Queues and ConcurrentLinkedQueue. These tools are crucial for managing tasks and data effectively in multi-threaded environments. By the end of this lesson, you'll understand how these collections facilitate thread-safe operations and optimize task management.

What You'll Learn

By the end of this lesson, you will:

  • Understand the differences between blocking and non-blocking queues.
  • Learn how to use the LinkedBlockingQueue to manage inter-thread communication.
  • Implement a ConcurrentLinkedQueue for non-blocking, thread-safe queue access.
  • See practical applications of these queues in managing tasks in multi-threaded systems.

Understanding Blocking Queues

A Blocking Queue, such as LinkedBlockingQueue, is a queue that controls thread execution by blocking operations when certain conditions are met. A thread attempting to remove an element from an empty queue will block until an element is available. Similarly, if the queue has a fixed capacity, a thread trying to add an element to a full queue will block until space becomes available. This behavior ensures efficient task management without overwhelming system resources.

Consider the following example:

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class TaskQueue {
    private BlockingQueue<String> taskQueue = new LinkedBlockingQueue<>(2); // Queue with a fixed capacity of 2

    public void addTask(String task) throws InterruptedException {
        taskQueue.put(task); // Blocks if the queue is full
        System.out.println("Task added: " + task);
    }

    public void executeTasks() throws InterruptedException {
        while (!taskQueue.isEmpty()) {
            String task = taskQueue.take(); // Blocks if the queue is empty
            System.out.println("Executing: " + task);
        }
    }
}

In this code:

  • BlockingQueue Initialization: The taskQueue is a LinkedBlockingQueue with a capacity of 2, meaning it can hold at most two tasks at a time.
  • addTask Method: Uses put() to add tasks. If the queue is full, the thread blocks until space is available, preventing task overflow.
  • executeTasks Method: Uses take() to retrieve and execute tasks. If the queue is empty, it blocks until a task is available, ensuring efficient resource utilization.

To see how this works in practice, consider the following main method:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        TaskQueue blockingQueue = new TaskQueue();

        blockingQueue.addTask("Task 1");
        blockingQueue.addTask("Task 2");

        System.out.println("Queue is full. The next task will block...");

        new Thread(() -> {
            try {
                System.out.println("Attempting to add Task 3...");
                blockingQueue.addTask("Task 3"); // This will block until space is available
            } catch (InterruptedException e) {
                System.out.println("Interrupted while waiting to add Task 3.");
            }
        }).start();

        Thread.sleep(2000); // Simulating delay before consuming tasks

        System.out.println("Removing a task...");
        blockingQueue.executeTasks(); // This will unblock the producer thread
    }
}

This program demonstrates how blocking behavior works:

  1. The queue is initialized with a capacity of 2, allowing "Task 1" and "Task 2" to be added immediately.
  2. A new thread attempts to add "Task 3" but blocks because the queue is full.
  3. After a short delay, the main thread starts executing tasks, making space in the queue.
  4. The blocked thread resumes execution and successfully adds "Task 3" once a slot is available.

This example highlights how LinkedBlockingQueue prevents excessive task production and enforces controlled task execution, making it ideal for managing workload distribution in multi-threaded environments.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal