Showing posts with label Java BlockingDeque. Show all posts
Showing posts with label Java BlockingDeque. Show all posts

Saturday, July 3, 2021

Java BlockingDeque With Examples

BlockingDeque interface in Java (added in Java 6) is a Deque that provides additional support for blocking operations. Here blocking the operations means that the operation will wait for the deque to become non-empty (means deque has at least one element) when retrieving an element, and wait for space to become available in the deque when storing an element.

Deque in Java

Deque is also an interface which was added in Java 6. Deque is short for "double ended queue". As the name suggests Deque supports element insertion and removal at both ends.

Java BlockingDeque

Like any BlockingQueue, BlockingDeque in Java is thread safe, does not permit null elements, and may (or may not) be capacity-constrained.

LinkedBlockingDeque class in Java is the implementation of the BlockingDeque interface.

BlockingDeque methods in Java

As already mentioned BlockingDeque in Java provides support for the blocking operations, but blocking methods come in four forms, categorized in the way these methods will handle operations that cannot be satisfied immediately, but may be satisfied at some point in the future:

  • Throw exception- Methods falling in this category will throw exception if blocked.
  • Return special value- This type of methods will return some value if need to wait, like false.
  • Blocks- This type of methods will wait if necessary for space to become available.
  • Times out- This type of methods will block for only a given maximum time limit before giving up.

These methods are summarized in the following table:

Monday, June 28, 2021

Java LinkedBlockingDeque With Examples

LinkedBlockingDeque in Java is an implementation of the BlockingDeque interface and it was added in Java 6.

LinkedBlockingDeque is an optionally bounded deque and it stores its elements as linked nodes. Since it is optionally bounded so it has constructor which takes initial capacity as parameter. In case capacity is not specified it is equal to Integer.MAX_VALUE.

Java LinkedBlockingDeque constructors

LinkedBlockingDeque in Java has three constructors-

  • LinkedBlockingDeque()- Creates a LinkedBlockingDeque with a capacity of Integer.MAX_VALUE.
  • LinkedBlockingDeque(Collection<? extends E> c)- Creates a LinkedBlockingDeque with a capacity of Integer.MAX_VALUE, initially containing the elements of the given collection, added in traversal order of the collection's iterator.
  • LinkedBlockingDeque(int capacity)- Creates a LinkedBlockingDeque with the given (fixed) capacity.

Here note that Linked nodes are dynamically created upon each insertion unless this would bring the deque above capacity. In case initial capacity is defined then the blocking method like put(E e) will wait if necessary for space to become available.

Since elements are stored as linked nodes so most of the operations like add(), addFirst(), put(), putFirst() run in constant time (ignoring time spent blocking). Exceptions include remove(object o), removeFirstOccurrence, removeLastOccurrence, contains, iterator.remove(), and the bulk operations, all of which run in linear time.

LinkedBlockingDeque Java Example code

Let's create a produce consumer bounded buffer using LinkedBlockingDeque which is an implmentation of BlockingDeque.

Values will be inserted in the LinkedBlockingDeque using put() method, which will block if the space is full.

Values will be retrieved from the LinkedBlockingDeque using take() method, which retrieves and removes the head of this queue, waiting if necessary until an element becomes available.

Here in the Produce class some delay is induced using sleep() method. You can see that in Consumer class, where it is taking elements out of the deque, no excpetion will be thrown but it will block. If you are using eclipse you can see that delay in the console when it is printing.

import java.util.concurrent.BlockingDeque;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;

public class LinkedBlockingDQDemo {
  public static void main(String[] args) {
    SharedClass buffer = new SharedClass();
    // Starting two threads
    ExecutorService executor = Executors.newFixedThreadPool(2);
    executor.execute(new Producer(buffer));
    executor.execute(new Consumer(buffer));
    executor.shutdown();
  }
}
/**
 * 
 */
class Producer implements Runnable{
  SharedClass buffer;
  Producer(SharedClass buffer){
    this.buffer = buffer;
  }
  @Override
  public void run() {
    for(int i = 0; i < 10; i++){
      buffer.put(i);
      if(i == 4){
        try {
          // introducing some delay using sleep
          Thread.sleep(1000);
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }
    }
  }
}
/**
 * 
 */
class Consumer implements Runnable{
  SharedClass buffer;
  Consumer(SharedClass buffer){
    this.buffer = buffer;
  }
  @Override
  public void run() {
    for(int i = 0; i < 10; i++){
      buffer.get();;
    }
  }    
}

//Shared class used by threads
class SharedClass{
  int i;
  // Bounded LinkedBlockingDeque of size 10
  BlockingDeque<Integer> linkedBlockingDeque = new LinkedBlockingDeque<Integer>(10);
    
  public void get(){
    try {
      // take method to get from blockingdeque
      System.out.println("Consumer recd - " + linkedBlockingDeque.take());
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
    
  public void put(int i){
    this.i = i;
    try {
      // putting in blocking deque
      linkedBlockingDeque.put(i);
      System.out.println("Putting - " + i);
    }
    catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 
  }
}

Output

Putting - 0
Putting - 1
Putting - 2
Putting - 3
Putting - 4
Consumer recd - 0
Consumer recd - 1
Consumer recd - 2
Consumer recd - 3
Consumer recd - 4
Putting - 5
Consumer recd - 5
Putting - 6
Consumer recd - 6
Putting - 7
Consumer recd - 7
Putting - 8
Consumer recd - 8
Putting - 9
Consumer recd - 9

That's all for this topic Java LinkedBlockingDeque With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Java BlockingDeque With Examples
  2. Java BlockingQueue With Examples
  3. Java LinkedBlockingQueue With Examples
  4. Java Phaser With Examples
  5. Java Concurrency Interview Questions And Answers

You may also like-

  1. Race Condition in Java Multi-Threading
  2. Why wait(), notify() And notifyAll() Methods Are in Object Class And Not in Thread Class
  3. Java ThreadLocal Class With Examples
  4. Functional Interfaces in Java
  5. Java Stream API Tutorial
  6. Heap Memory Allocation in Java
  7. static Keyword in Java With Examples
  8. Data Access in Spring Framework