Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Implementing Two Java Blocking Queues for Thread Communication

Tech Apr 29 32

Implementing Two Java Blocking Queues for Thread Communication

Overview

Java provides robust blocking queue implementations to manage thread synchronization and communication. This example uses ArrayBlockingQueue and LinkedBlockingQueue to demonstrate sequential data transfer between two threads.

Implementation Steps

  1. Initialize two distinct blocking queues
  2. Create two worker threads: one produces elements to the first queue, and another consumes those elements and transfers them to the second queue
  3. Leverage built-in blocking behavior of put and take to handle synchronization automatically

Code Implementation

Step 1: Initialize Blocking Queues
// Fixed-capacity ArrayBlockingQueue with 15 slots
ArrayBlockingQueue<String> dataChannel1 = new ArrayBlockingQueue<>(15);
// Unbounded LinkedBlockingQueue
LinkedBlockingQueue<String> dataChannel2 = new LinkedBlockingQueue<>();
Step 2: Create Worker Threads
// Producer thread: sends data to dataChannel1
Thread dataProducer = new Thread(() -> {
    try {
        String message = "Processing Request #101";
        dataChannel1.put(message);
        System.out.println("Produced and sent to Channel 1: " + message);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        System.err.println("Producer thread interrupted");
    }
});

// Consumer-Forwarder thread: retrieves from dataChannel1 and sends to dataChannel2
Thread dataTransporter = new Thread(() -> {
    try {
        String receivedMessage = dataChannel1.take();
        System.out.println("Retrieved from Channel 1: " + receivedMessage);
        dataChannel2.put(receivedMessage);
        System.out.println("Forwarded to Channel 2: " + receivedMessage);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        System.err.println("Transporter thread interrupted");
    }
});

// Start both threads
dataProducer.start();
dataTransporter.start();

Blocking Mechanism Explanation

The put() method blocks if dataChannel1 reaches capacity, and take() blocks if dataChannel1 is empty, ensuring no race conditions or manual synchronization logic are needed.

Usage Scenario

This patteern is ideal for decoupling processing stages in multi-threaded aplications, such as pipeline architectures where raw data is first collected and then processed.

Key Differences Between the Two Queues

Feature ArrayBlockingQueue LinkedBlockingQueue
Capacity Fixed (must be specified) Optional (unbounded by default)
Underlying Structure Array-based (contiguous memory) Doubly linked list (dynamic nodes)
Performance Faster for bounded, predictable loads Better for unbounded, variable loads
Locking Strategy Single lock (for both put/take) Separate locks for put and take

Related Articles

SBUS Signal Analysis and Communication Implementation Using STM32 with Fus Remote Controller

Overview In a recent project, I utilized the SBUS protocol with the Fus remote controller to control a vehicle's basic operations, including movement, lights, and mode switching. This article is aimed...

Comprehensive Guide to Hive SQL Syntax and Operations

This article provides a detailed walkthrough of Hive SQL, categorizing its features and syntax for practical use. Hive SQL is segmented into the following categories: DDL Statements: Operations on...

Understanding the MP4 File Format and Analysis

Table of Contents Overview Fundamentals of the MP4 Format Key Concepts of the Container Format Box Structure Track Samples Sample Tables Chunks Detailed Explanation of Core Boxes Additional Boxes...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.