The LinkedBlockingQueue and ConcurrentLinkedQueue have frequently used queues and concurrent applications in java.

These queues use the same data structures. There are many differences between them.

Table of Content :

What is LinkedBlockingQueue?

LinkedBlockingQueue is an optionally-bounded blocking queue based on linked nodes, which means its size is specified if needed.

  • This queue orders elements FIFO (first-in-first-out). The head of the queue is that element that has been in the queue for the longest time.
  • The tail of the queue is that element that has been in the queue the shortest time.
  • The new elements are inserted at the tail of the queue, and the queue retrieval operations obtain elements at the head of the queue.
  • This kind of type has a higher throughput than array-based queues but less predictable performance in most concurrent applications.
  • The LinkedBlockingQueue implementations are designed to be used primarily for producer-consumer queues.


BlockingQueue<Integer>  unboundedQueue = new LinkedBlockingQueue<Integer> ();
  

If we want to specify size,

BlockingQueue<Integer> boundedQueue = new LinkedBlockingQueue<Integer> (10);

LinkedBlockingQueue Example

package com.javacodestuffs.core.collections.queue; import java.util.concurrent.* ; import java.util.* ; class Producer implements Runnable { private BlockingQueue <Integer> queue; public Producer(BlockingQueue <Integer> queue) { this.queue = queue; } public void run() { try { for (int i = 0; i < 10; i++) { Integer number = produce(); queue.put(number); System.out.println("Producer: created " + number); } queue.put( - 1); // indicates end of producing System.out.println("Producer : STOPPED."); } catch(InterruptedException ie) { ie.printStackTrace(); } } private Integer produce() { Random random = new Random(); Integer number = random.nextInt(100); try { Thread.sleep(random.nextInt(1000)); } catch(InterruptedException ie) { ie.printStackTrace(); } return number; } }

Consumer.java

package com.javacodestuffs.core.collections.queue; import java.util.concurrent.*; import java.util.*; class Consumer implements Runnable { private BlockingQueue <Integer> queue; public Consumer(BlockingQueue <Integer> queue) { this.queue = queue; } public void run() { try { while (true) { Integer number = queue.take(); if (number == -1) { System.out.println("Consumer: STOPPED."); break; } consume(number); } } catch(InterruptedException ie) { ie.printStackTrace(); } } private void consume(Integer number) { // fake consuming time Random random = new Random(); try { Thread.sleep(random.nextInt(1000)); } catch(InterruptedException ie) { ie.printStackTrace(); } System.out.println("Consumer: processed " + number); } }

package com.javacodestuffs.core.collections.queue; import java.util.concurrent.*; import java.util.*; public class LinkedBlockingQueueExample { public static void main(String[] args) { BlockingQueue <Integer> queue = new LinkedBlockingQueue <Integer> (10); Thread producer = new Thread(new Producer(queue)); Thread consumer = new Thread(new Consumer(queue)); producer.start(); consumer.start(); } } output: Producer: created 24 Consumer: processed 24 Producer: created 7 Consumer: processed 7 Producer: created 8 Consumer: processed 8 Producer: created 44 Consumer: processed 44 Producer: created 41 Producer: created 21 Producer: created 38 Consumer: processed 41 Producer: created 3 Consumer: processed 21 Producer: created 10 Consumer: processed 38 Consumer: processed 3 Consumer: processed 10 Producer: created 67 Producer : STOPPED. Consumer: processed 67 Consumer: STOPPED.

What is ConcurrentLinkedQueue ?

ConcurrentLinkedQueue is an unbounded thread-safe queue based on linked nodes.

  • The new elements are inserted at the tail of the queue, and the queue retrieval operations obtain elements at the head of the queue.
  • A ConcurrentLinkedQueue is an appropriate choice when many threads will share access to a common collection.
  • It does not permit the use of null elements.
ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();

We can create this kind of queue from the collection.

Collection<Integer> listOfNumbers = Arrays.asList(1,2,3,4,5); ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<Integer> (listOfNumbers);

ConcurrentLinkedQueue Example

package com.javacodestuffs.core.collections.queue; import java.util.concurrent.*; import java.util.*; public class ConcurrentLinkedQueueExample { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(4); Queue <Integer> conQueue = new ConcurrentLinkedQueue <Integer> (); // One Producer thread executor.execute(new ConcurrentProducer(conQueue)); // Two Consumer thread System.out.println(); executor.execute(new ConcurrentConsumer(conQueue)); executor.execute(new ConcurrentConsumer(conQueue)); System.out.println(); executor.shutdown(); } } //Producer class ConcurrentProducer implements Runnable { Queue <Integer> conQueue; ConcurrentProducer(Queue <Integer> conQueue) { this.conQueue = conQueue; }@Override public void run() { for (int i = 0; i < 6; i++) { System.out.println("Adding element to the queue : " + i); conQueue.add(i); } } } //Consumer class ConcurrentConsumer implements Runnable { Queue <Integer> conQueue; ConcurrentConsumer(Queue <Integer> conQueue) { this.conQueue = conQueue; }@Override public void run() { for (int i = 0; i < 3; i++) { try { TimeUnit.MILLISECONDS.sleep(100); System.out.println("Thread Name -" + Thread.currentThread().getName() + " Consumer retrieved element : " + conQueue.poll()); } catch(InterruptedException e) { e.printStackTrace(); } } } } output: Adding element to the queue : 0 Adding element to the queue : 1 Adding element to the queue : 2 Adding element to the queue : 3 Adding element to the queue : 4 Adding element to the queue : 5 Thread Name -pool-1-thread-2 Consumer retrieved element : 0 Thread Name -pool-1-thread-3 Consumer retrieved element : 1 Thread Name -pool-1-thread-2 Consumer retrieved element : 2 Thread Name -pool-1-thread-3 Consumer retrieved element : 3 Thread Name -pool-1-thread-2 Consumer retrieved element : 4 Thread Name -pool-1-thread-3 Consumer retrieved element : 5


Similarities between LinkedBlockingQueue
and ConcurrentLinkedQueue

  • Both the classes and their iterators implement all of the optional methods of the Queue and Iterator interfaces.
  • Both use linked nodes to stores their data.
  • Both are used in concurrent environments and applications.
  • Both classes are members of the Java Collections Framework.
  • Both classes are included in java 1.5 version.
  • Both classes has a iterator which is a "weakly consistent" iterator that will never throw ConcurrentModificationException.
  • Both classes does not permits the use of null elements.

Differences between LinkedBlockingQueue and ConcurrentLinkedQueue


The following are some major differences between them.

LinkedBlockingQueue ConcurrentLinkedQueue
1). Its locking based on two-lock queue algorithm ConcurrentLinkedQueue is based on the famous algorithm by Maged M. Michael and Michael L. Scott for non-blocking lock-free queues.
2). Its lock based queue. Its not a lock based queue.
3). It is a blocking queue so, implements the BlockingQueue interface. It is a non-blocking queue so,not implements the BlockingQueue interface.
4). LinkedBlockingQueue have higher throughput than array-based queues but less predictable performance in most concurrent applications.. A ConcurrentLinkedQueue is an appropriate choice when many threads will share access to a common collection.
5). LinkedBlockingQueue provides blocking methods such as put and take. ConcurrentLinkedQueue does not provide put and take methods.


Articles/Questions related to
LinkedBlockingQueue vs ConcurrentLinkedQueue in Java
using Java


Why use ConcurrentLinkedQueue when we have LinkedBlockingQueue?

The ConcurrentLinkedQueue is wait-free, not merely lock-free (what's the difference?) while LinkedBlockingQueue must remain locking by its very nature.

We can use ConcurrentLinkedQueue with LinkedBlockingQueue and poll, but the implementation would remain locking, reducing the concurrency that you could get out of your system.

List add() Method in Java with Examples
Collections Class in Java
Iterable interface in java
Priority Queue in Java
Differences between ArrayList and Vector
Java ArrayList removeAll() Examples
Hashmap vs Concurrent Hashmap in Java

In this article, we have seen the  LinkedBlockingQueue vs ConcurrentLinkedQueue in Java with examples. All source code in the article can be found in the GitHub repository.