Java LinkedBlockingQueue

In this tutorial, we will learn about java.util.concurrent.LinkedBlockingQueue, its features with explanation and working examples of it including explanation.

LinkedBlockingQueue class

java.util.concurrent.LinkedBlockingQueue is a class and have an optionally-bounded blocking queue that is backed by a linked list data structure. It is a thread-safe class and allows multiple threads can access the queue elements without exposing to the concurrent modification exception.

Behaviour of LinkedBlockingQueue

  1. It has an optional capacity bound that can be set when the queue is created, but if not specified, it can hold elements up to Integer.MAX_VALUE.
  2. It is a blocking queue, which means that if the queue is full, a thread attempting to insert an element will be blocked until space becomes available, and if the queue is empty, a thread attempting to remove an element will be blocked until an element becomes available.
  3. It follows a FIFO (first-in, first-out) order in which the elements are added and removed from the queue.
  4. It is thread-safe, which means multiple threads can access it without any issues.

LinkedBlockingQueue example with producer and consumer:

In the following example, we will use only one producer and one consumer threads. While producer thread will produce the messages to the LinkedBlockingQueue and consumer thread will consume the messages from the LinkedBlockingQueue which was produced by producer thread.

CopiedCopy Code
import java.util.concurrent.LinkedBlockingQueue;
public class LinkedBlockingQueueExample {
    public static void main(String[] args) throws InterruptedException {
        LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
        // Producer thread
        Runnable producer = new Runnable() {
			@Override
			public void run() {
				try {
	                while (true) {
	                    String message = "Message " + System.currentTimeMillis();
	                    queue.put(message);
	                    System.out.println("Produced: " + message);
	                    Thread.sleep(1000);
	                }
	            } catch (InterruptedException e) {
	                e.printStackTrace();
	            }
			}
		};
        // Consumer thread
        Runnable consumer = new Runnable() {
			@Override
			public void run() {
				try {
	                while (true) {
	                    String message = queue.take();
	                    System.out.println("Consumed: " + message);
	                }
	            } catch (InterruptedException e) {
	                e.printStackTrace();
	            }
			}
		};
		new Thread(producer).start();
        new Thread(consumer).start();
    }
}

Output :

Produced: Message 1682734955755
Consumed: Message 1682734955755
Produced: Message 1682734956765
Consumed: Message 1682734956765
Produced: Message 1682734957781
Consumed: Message 1682734957781
Produced: Message 1682734958782
Consumed: Message 1682734958782
Produced: Message 1682734959795
Consumed: Message 1682734959795

Explanation :

In the above example, we create a LinkedBlockingQueue with an unbounded capacity. We then created two threads, a producer thread that adds messages to the queue and a consumer thread that removes messages from the queue. The producer thread adds a message to the queue every 1 second using the put() method, and the consumer thread removes messages from the queue using the take() method.

Both threads run in an infinite loop until the program is terminated.

LinkedBlockingQueue example with single thread for producer and consumer:

The following is an example with single thread used for producing and consuming messages from the java.util.concurrent.LinkedBlockingQueue

CopiedCopy Code
import java.util.concurrent.LinkedBlockingQueue;
public class LinkedBlockingQueueExample {
    public static void main(String[] args) throws InterruptedException {
        LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
        // Add elements to the queue
        queue.add("one");
        queue.add("two");
        queue.add("three");
        // Remove elements from the queue
        System.out.println(queue.take());
        System.out.println(queue.take());
        System.out.println(queue.take());
    }
}

Output :

one
two
three

Explanation :

In the above example, we created a LinkedBlockingQueue with an unbounded capacity. We then added three elements to the queue using the add() method. We then remove the elements from the queue using the take() method.

Since we added three elements to the queue, we remove three elements from the queue in the order they were added using the take() method.

Conclusion :

In this tutorial, we have covered LinkedBlockingQueue its features along with the working examples of it including explanation.