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 :
- Introduction
- What is LinkedBlockingQueue?
- LinkedBlockingQueue Example
- What is ConcurrentLinkedQueue ?
- ConcurrentLinkedQueue Example
- Similarity between LinkedBlockingQueue and ConcurrentLinkedQueue
- Differences between LinkedBlockingQueue and ConcurrentLinkedQueue
- Questions/Articles related to LinkedBlockingQueue vs ConcurrentLinkedQueue in Java
- Summary
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
Producer.java
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 ExamplesCollections 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.
0 Comments
Post a Comment