Showing posts with label Java blocking queue. Show all posts
Showing posts with label Java blocking queue. Show all posts

Wednesday, January 3, 2024

Java Program to Create Your Own BlockingQueue

This post shows how you can create your own BlockingQueue in Java using ReentrantLock and Condition interface. Condition interface provides method await and signal which work the same way as wait and notify.

BlockingQueue Java Program

Here we have a class called BufferClass which has an array of type Object, whose length is 5. So, 5 is the bound for buffer, if 5 values are already added to the array it will be blocked until at least one value is retrieved from the array.

put() and take() methods are used to add values and retrieve values from an array respectively.

BufferClass

 
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class BufferClass {
  final Lock lock = new ReentrantLock();
  // Conditions
  final Condition produce  = lock.newCondition(); 
  final Condition consume = lock.newCondition(); 

  final Object[] valueArr = new Object[5];
  int putIndex, takeIndex;
  int count;

  public void put(Object x) throws InterruptedException {
    //System.out.println("count -- " + count);
    //System.out.println("Array length -- " + valueArr.length);
    lock.lock();
    try {
      while (count == valueArr.length){    
        produce.await();
        //System.out.println("Awaiting");
      }
   
      valueArr[putIndex] = x;
      System.out.println("Adding - " + x);
      if (++putIndex == valueArr.length){
        putIndex = 0;
      }
      // increment count
      ++count;
      consume.signal();
    } finally {
      lock.unlock();
    }
  }

  public Object take() throws InterruptedException {
    lock.lock();
    try {
      while (count == 0){
        consume.await();
      }
      Object x = valueArr[takeIndex];
      System.out.println("Retrieving - " + x);
      if (++takeIndex == valueArr.length){
        takeIndex = 0;
      }
      // reduce the count
      --count;
      // signal producer
      produce.signal();
      return x;
    } finally {
      lock.unlock();
    }
  }
}

To test this BufferClass we have another class BufferClassDemo where two threads are created, one will add values to the buffer and another will retrieve values from the buffer. Here 10 values are added, BufferClass should ensure if 5 values are already added any attempt to add any further value should be blocked. Same way if the buffer is empty any attempt to retrieve value should be blocked.

 
public class BufferClassDemo {
 
 public static void main(String[] args) {
  BufferClass bufferClass = new BufferClass();
  // Creating two threads
  Thread producer = new Thread(new Producer(bufferClass));
  Thread consumer = new Thread(new Consumer(bufferClass)); 
  // starting threads
  producer.start();
  consumer.start();
 }
}

class Producer implements Runnable {
  private BufferClass bufferClass;    
  public Producer(BufferClass bufferClass){
    this.bufferClass = bufferClass;
  }
  @Override
  public void run() {
    for (int i = 1; i <= 10; i++) {
      try {
        //Thread.sleep(10);                            
        bufferClass.put(i);                            
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}

class Consumer implements Runnable {
  private BufferClass bufferClass;    
  public Consumer(BufferClass bufferClass){
    this.bufferClass = bufferClass;
  }
  @Override
  public void run() {
    for (int i = 1; i <= 10; i++) {
      try {
        // Thread.sleep(500);
        bufferClass.take();               
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}

Output

Output from one of the run. Note that output may vary but the condition of not having more than 5 elements and blocking any attempt to add should hold.

Adding - 1
Adding - 2
Adding - 3
Adding - 4
Adding - 5
Retrieving - 1
Retrieving - 2
Retrieving - 3
Retrieving - 4
Retrieving - 5
Adding - 6
Adding - 7
Adding - 8
Retrieving - 6
Retrieving - 7
Retrieving - 8
Adding - 9
Retrieving - 9
Adding - 10
Retrieving - 10

That's all for this topic Java Program to Create Your Own BlockingQueue. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Java ArrayBlockingQueue With Examples
  2. How to Run Threads in Sequence in Java
  3. How to Create Deadlock in Java
  4. Print Odd-Even Numbers Using Threads And wait-notify Java Program
  5. Producer-Consumer Java Program Using ArrayBlockingQueue

You may also like-

  1. Convert String to Byte Array Java Program
  2. How to Remove Elements From an Array Java Program
  3. How to Convert Date And Time Between Different Time-Zones in Java
  4. Callable and Future in Java With Examples
  5. Volatile Keyword in Java With Examples
  6. PermGen Space Removal in Java 8
  7. Spliterator in Java
  8. Multi-Catch Statement in Java Exception Handling

Sunday, January 15, 2023

Java DelayQueue With Examples

DelayQueue in Java is an implementation of BlockingQueue interface and is added in Java 5 along with other concurrent utilities like CyclicBarrier, Exchanger, ConcurentSkipListMap, CopyOnWriteArraySet etc.

DelayQueue in Java is an unbounded implementation of BlockingQueue, that's where it is different from the other implementations of BlockingQueue like ArrayBlockingQueue (Always bounded) and LinkedBlockingQueue (both bounded and unbounded options). Though it is similar to PriorityBlockingQueue in this behaviour as PriorityBlockingQueue is also unbounded.

DelayQueue stores Delayed elements

DelayQueue in Java is a special implementation of BlockingQueue as it can only store elements of type Delayed and an element can only be retrieved from DelayQueue when its delay has expired.

Delayed interface which defines the type for the elements in the DelayQueue has one method

  • getDelay(TimeUnit unit)- Returns the remaining delay associated with this object, in the given time unit.

Delayed interface also extends Comparable interface so compareTo(T o) method should also be implemented. This method implementation will decide whether you want to retrieve elements in ascending order of delay or descending.

According to JavaDocs "An implementation of this interface must define a compareTo method that provides an ordering consistent with its getDelay method."

So, just to sum it up; DelayQueue stores elements of type Delayed. When you implement Delayed interface two methods have to be implemented getDelay(TimeUnit unit) and compareTo(T o).

Ordering in Java DelayQueue

DelayQueue orders its elements (of type Delayed) based on the remaining delay associated with the element as returned by the getDelay() method. The head of the queue is the Delayed element whose delay expired furthest in the past where as the tail of the queue is the Delayed element with the longest remaining delay expiration time.

Producer Consumer Java example using DelayQueue

Let's create a producer consumer using the DelayQueue. There is also a class DelayClass which implements Delayed interface and implements the required methods- getDelay() and compareTo(). DelayQueue will store objects of DelayClass.

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayQDemo {
  public static void main(String[] args) {
    // delay of 2 seconds
    final long delay = 2000;
    BlockingQueue<DelayClass> delayQ = new DelayQueue<DelayClass>();
      
    // Producer thread
    new Thread(){
      @Override
      public void run() {
        for(int i = 0; i < 5; i++){
          try {
            // putting elements in delay queue
            delayQ.put(new DelayClass("item"+i, delay));
            Thread.sleep(50);
          } catch (InterruptedException e) {
            System.out.println("Error while putting values in the Queue "
             + e.getMessage());
          }
        }
      }
    }.start();
      
    // Consumer thread
    new Thread(){
      @Override
      public void run() {
        for(int i = 0; i < 5; i++){
          try {
            // retrieving elements from delay queue
            System.out.println(" Consumer got - " + delayQ.take());
            Thread.sleep(500);
          } catch (InterruptedException e) {
            System.out.println("Error while retrieving value from the Queue "
             + e.getMessage());
          }
        }
      }
    }.start();
  }
}

// Delayed interface implementing class
class DelayClass implements Delayed{
  private String item;
  private long expireTime;
  DelayClass(String item, long delay){
    this.item = item;
    // Expiretime is currenttime+delay, so if delay of 2 sec is required
    // expiration from queue will hppn after
    // currenttime + 2 sec
    this.expireTime = System.currentTimeMillis() + delay;
  }
    
  @Override
  public long getDelay(TimeUnit unit) {
    long diff = expireTime - System.currentTimeMillis();
    return unit.convert(diff, TimeUnit.MILLISECONDS);
  }
    
  @Override
  public int compareTo(Delayed o) {
    if(this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)){
      return -1;
    }
    if(this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)){
      return 1;
    }
    return 0;        
  }
    
  public String toString(){
    return "item = " + item + " expireTime = " + expireTime;
  } 
}

Output

Consumer got - item = item0 expireTime = 1458998017469
Consumer got - item = item1 expireTime = 1458998017531
Consumer got - item = item2 expireTime = 1458998017594
Consumer got - item = item3 expireTime = 1458998017656
Consumer got - item = item4 expireTime = 1458998017719

Here it can be seen elements are retrieved from the queue only after the delay expires.

Points to remember

  1. DelayQueue in Java stores element of type Delayed.
  2. Element is retrieved from DelayQueue only when its delay has expired.
  3. The head of the queue is thatDelayed element whose delay expired furthest in the past.
  4. If no delay has expired there is no head and poll will return null.
  5. Expiration occurs when an element's getDelay(TimeUnit tu) method returns a value less than or equal to zero.

Reference: https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/concurrent/DelayQueue.html

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


Related Topics

  1. Java SynchronousQueue With Examples
  2. Java BlockingDeque With Examples
  3. Java LinkedTransferQueue With Examples
  4. Java ReentrantReadWriteLock With Examples
  5. Java Semaphore With Examples

You may also like-

  1. ConcurrentHashMap in Java With Examples
  2. Deadlock in Java Multi-Threading
  3. Synchronization in Java - Synchronized Method And Block
  4. Java Collections Interview Questions And Answers
  5. Java Lambda Expression And Variable Scope
  6. Autowiring in Spring Using @Autowired and @Inject Annotations
  7. Try-With-Resources in Java With Examples
  8. Java Program to Find The Longest Palindrome in a Given String

Saturday, December 31, 2022

Java LinkedTransferQueue With Examples

LinkedTransferQueue is added in Java 7 and it is an implementation of TransferQueue interface.

TransferQueue interface in Java

It will be worthwhile to spend some time knowing the TransferQueue interface here.

TransferQueue interface, also added in Java 7, extends BlockingQueue interface. The extra functionality provided by TransferQueue interface is that it provides blocking method which will wait until other thread receives your element.

That's how it differs from BlockingQueue where you can only put element into queue or retrieve element from queue and block if queue is full (while you are putting elements) or block if queue is empty (while you are retrieving elements). So BlockingQueue won't block until consumer thread removes any particular element (Though SynchronousQueue provides that kind of functionality but more as one-to-one handoff, not as a queue.)

TransferQueue has a blocking method transfer(E e) which will ensure that the element is transferred to the consumer, it will wait if required to do so. More precisely, transfers the specified element immediately if there exists a consumer already waiting to receive it (in BlockingQueue.take() or timed poll), else waits until the element is received by a consumer.

TransferQueue also has put() method, just like BlockingQueue which will just enqueue the element without waiting for consumer to retrieve the element.

It also has non-blocking and time-out tryTransfer() method-

  • tryTransfer(E e)- Transfers the element to a waiting consumer immediately, if possible.
  • tryTransfer(E e, long timeout, TimeUnit unit)- Transfers the element to a consumer if it is possible to do so before the timeout elapses.

TransferQueue also has querying methods like getWaitingConsumerCount() and hasWaitingConsumer()

  • getWaitingConsumerCount()- Returns an estimate of the number of consumers waiting to receive elements via BlockingQueue.take() or timed poll.
  • hasWaitingConsumer()- Returns true if there is at least one consumer waiting to receive an element via BlockingQueue.take() or timed poll.

Java LinkedTransferQueue

LinkedTransferQueue, as already mentioned is an implementation of the TransferQueue. LinkedTransferQueue in Java is an unbounded queue and stores elements as linked nodes.

LinkedTransferQueue orders elements FIFO (first-in-first-out) with respect to any given producer. The head of the queue is that element that has been on the queue the longest time for some producer. The tail of the queue is that element that has been on the queue the shortest time for some producer.

Java LinkedTransferQueue constructors

  • LinkedTransferQueue()- Creates an initially empty LinkedTransferQueue.
  • LinkedTransferQueue(Collection<? extends E> c)- Creates a LinkedTransferQueue initially containing the elements of the given collection, added in traversal order of the collection's iterator.

Producer Consumer Java example using LinkedTransferQueue

Let's create a producer consumer using LinkedTransferQueue. There is a producer thread which will put elements into the queue and a consumer thread which will retrieve elements from the queue. Also a shared class which will be used by both producer and consumer threads.

To show the functionality of transfer() method delay is induced in consumer thread, since elements are stored using transfer() method so the producer will wait unless until consumer thread retrieves the element. Producer won't keep on adding the element to the queue even if consumer thread is sleeping it gets blocked.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TransferQueue;

public class LinkedTQDemo {
  public static void main(String[] args) {
    // buffer class used by both threads
    SharedTQ buffer = new SharedTQ();
    // Starting two threads
    ExecutorService executor = Executors.newFixedThreadPool(2);
    // Executing producer
    executor.execute(new TProd(buffer));
    // Executing consumer
    executor.execute(new TCon(buffer));
    executor.shutdown();
  }
}


/**
 * Producer class
 */
class TProd implements Runnable{
  SharedTQ buffer;
  TProd(SharedTQ buffer){
    this.buffer = buffer;
  }
  @Override
  public void run() {
    for(int i = 0; i < 5; i++){
      buffer.put(i);
    }
  }
}

/**
 * Consumer class
 */
class TCon implements Runnable{
  SharedTQ buffer;
  TCon(SharedTQ buffer){
    this.buffer = buffer;
  }
  @Override
  public void run() {
    for(int i = 0; i < 5; i++){
      try {
        // introducing some delay using sleep
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        System.out.println("Error while putting in the queue " + e.getMessage());
      }
      buffer.get();
    }
  }    
}

//Shared class used by threads
class SharedTQ{
  int i;
  // TransferQueue
  TransferQueue<Integer> ltQueue = new LinkedTransferQueue<Integer>();
  
  public void get(){
    try {
      // take method to get from TransferQueue
      System.out.println("Consumer recd - " + ltQueue.take());
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
    
  public void put(int i){
    this.i = i;
    try {
      System.out.println("Putting - " + i);
      // putting in TransferQueue
      ltQueue.transfer(i);        
    }
    catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 
  }
}

Output

Putting - 0
Consumer recd - 0
Putting - 1
Consumer recd - 1
Putting - 2
Consumer recd - 2
Putting - 3
Consumer recd - 3
Putting - 4
Consumer recd - 4

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


Related Topics

  1. Java ArrayBlockingQueue With Examples
  2. Java SynchronousQueue With Examples
  3. Java BlockingDeque With Examples
  4. Java Semaphore With Examples
  5. Java Concurrency Interview Questions And Answers

You may also like-

  1. ConcurrentSkipListMap in Java With Examples
  2. Lambda Expressions in Java 8
  3. Volatile Keyword in Java With Examples
  4. Multi-Catch Statement in Java Exception Handling
  5. super Keyword in Java With Examples
  6. static Method Overloading or Overriding in Java
  7. Add Double Quotes to a String Java Program
  8. Spring Bean Life Cycle

Monday, April 4, 2022

Java BlockingQueue With Examples

BlockingQueue interface in Java is added in Java 5 with in the java.util.concurrent package along with other concurrent utilities like CyclicBarrier, Phaser, ConcurrentHashMap, ReentranctLock etc.

Java BlockingQueue

BlockingQueue in Java, as the name suggests is a queue that can block the operations. Which means BlockingQueue supports operations that wait for the queue to become non-empty when retrieving an element, and wait for space to become available in the queue when storing an element.

If we take the Producer-Consumer problem as example where we have two threads, one inserting the elements in the queue and another thread retrieving the elements from the queue then using the BlockingQueue can block the operation in the following scenarios-

  • If Producer thread is trying to insert an element when the queue is already full.
  • If Consumer thread is trying to retrieve an element when the queue is empty.

For that BlockingQueue interface has two specific methods-

  1. put(E e)- Inserts the specified element into this queue, waiting if necessary for space to become available.
  2. take()- Retrieves and removes the head of this queue, waiting if necessary until an element becomes available.

Java BlockingQueue Methods

BlockingQueue methods for inserting, removing and examining elements come in four forms. These set of methods have different functionality if the operationcan not be carried out when requested.

Throws exception Special value Blocks Times out
Insert add(e) offer(e) put(e) offer(e, time, unit)
Remove remove() poll() take() poll(time, unit)
Examine element() peek() not applicable not applicable
  1. Methods in first column throw exception if the operation cannot be executed immediately i.e. these methods won't block.
  2. Methods in second column return a special value (either null or false, depending on the operation) if operation cannot be performed immediately.
  3. Methods in third column will block the current thread indefinitely until the operation can succeed.
  4. Methods in fourth column block for only a given maximum time limit before giving up.

BlockingQueue Superinterfaces

BlockingQueue extends Collection, Queue and Iterable interfaces so it inherits all Collection and Queue methods.

As example add(E e), remove(Object o) from the Collection interface which are different from the other two methods put() and take() in the way that add() and remove() don't block, they throw exception if the operation cannot be executed immediately.

poll() and peek() operations from Queue interface where

  • poll()- Retrieves and removes the head of this queue, or returns null if this queue is empty.
  • peek()- Retrieves, but does not remove, the head of this queue, or returns null if this queue is empty.

BlockingQueue Implementations in Java

Classes implementing BlockingQueue interface in Java are-

Features of the Java BlockingQueue

Some of the important features of the BlockingQueue in Java are as follows which are shared by all the implementations.

1. No nulls in BlockingQueue

A BlockingQueue does not accept null elements. Implementations (like LinkedBlockingQueue or ArrayBlockingQueue) throw NullPointerException on attempts to add, put or offer a null.

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BQDemo {
  public static void main(String[] args) {
    BlockingQueue<String> arrayBlockingQ = new ArrayBlockingQueue<String>(2);
    try {
      arrayBlockingQ.put(null);
    } catch (InterruptedException e) {
      System.out.println("Exception occurred" + e);
    }
  }
}

Output

Exception in thread "main" java.lang.NullPointerException
 at java.util.concurrent.ArrayBlockingQueue.checkNotNull(Unknown Source)
 at java.util.concurrent.ArrayBlockingQueue.put(Unknown Source)
 at org.netjs.prgrm.BQDemo.main(BQDemo.java:10)

2. Java BlockingQueue implementations are thread-safe

BlockingQueue implementations like ArrayBlockingQueue, LinkedBlockingQueue are thread-safe. All queuing methods use internal locks or other forms of concurrency control to achieve their effects atomically.

Since BlockingQueue interface also extends Collection interface so it inherits operations from Collection interface also. However, the bulk Collection operations addAll, containsAll, retainAll and removeAll are not necessarily performed atomically unless specified otherwise in an implementation. So it is possible, for example, for addAll(c) to fail (throwing an exception) after adding only some of the elements in c.

Java BlockingQueue capacity

BlockingQueue implementations are of two types-

  • Bounded- A bounded queue is a queue that has a fixed capacity.
  • Unbounded- An unbounded queue is a queue that can grow indefinitely.

Note that there are BlockingQueue implementations that can be created as both bounded or unbounded.

For a bounded BlockingQueue implementation we have to create the BlockingQueue with the given (fixed) capacity.

For example, ArrayBlockingQueue for which capacity has to be specified.

BlockingQueue<String> arrayBlockingQ = new ArrayBlockingQueue<String>(2);

In case of LinkedBlockingQueue and PriorityBlockingQueue both can be bounded or unbounded.

BlockingQueue<String> linkedBlockingQ = new LinkedBlockingQueue<String>(2);
        
Queue<String> linkedBlockingQ = new LinkedBlockingQueue<String>();

Note that a BlockingQueue without any intrinsic capacity constraints always reports a remaining capacity of Integer.MAX_VALUE.

BlockingQueue Usage in Java

BlockingQueue implementations are designed to be used primarily for producer-consumer queues because of the blocking methods put() and take() which facilitates inter-thread communication.

It can also be used as a bounded buffer. Let's say you have a ArrayBlockingQueue of capacity 10. So one thread can keep putting values in it and another thread can read from it once the buffer is full thus creating a bounded buffer.

At any time if all 10 slots are filled put() will block and same way for take() if there are no elements to read it will block.

BlockingQueue Java example

public static void main(String[] args) {
  BlockingQueue<String> arrayBlockingQ = new ArrayBlockingQueue<String>(2);
  try {
    arrayBlockingQ.put("A");
    arrayBlockingQ.put("B");
    System.out.println("------ 1 -------");
    arrayBlockingQ.forEach(a->System.out.println(a));
    arrayBlockingQ.take();
    arrayBlockingQ.put("C");
    System.out.println("------ 2 -------");
    
    arrayBlockingQ.forEach(a->System.out.println(a));
  } catch (InterruptedException e) {
    System.out.println("Exception occurred" + e);
  }
}

Output

------ 1 -------
A
B
------ 2 -------
B
C

Here it can be seen how elements are added at the end, while taking it is retrieved from the head of the queue.

Reference: https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/concurrent/BlockingQueue.html

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


Related Topics

  1. CopyOnWriteArrayList in Java With Examples
  2. Difference Between CountDownLatch And CyclicBarrier in Java
  3. Java Phaser With Examples
  4. Executor And ExecutorService in Java With Examples
  5. Java Concurrency Interview Questions And Answers

You may also like-

  1. Race Condition in Java Multi-Threading
  2. Inter-thread Communication Using wait(), notify() And notifyAll() in Java
  3. Java ThreadLocal Class With Examples
  4. How to Remove Duplicate Elements From an ArrayList in Java
  5. Difference Between Comparable and Comparator in Java
  6. Functional Interface Annotation in Java
  7. PermGen Space Removal in Java 8
  8. Dependency Injection in Spring Framework

Monday, March 7, 2022

Java PriorityBlockingQueue With Examples

PriorityBlockingQueue class in Java is an implementation of BlockingQueue interface. PriorityBlockingQueue class uses the same ordering rules as the PriorityQueue class, in fact PriorityBlockingQueue can be termed as the thread-safe alternative of the PriorityQueue as it has blocking retrieval operations.

PriorityBlockingQueue is logically unbounded

While PriorityBlockingQueue is logically unbounded, attempted additions may fail due to resource exhaustion (causing OutOfMemoryError). That's where it differs from the other implementations of BlockingQueue like ArrayBlockingQueue (Always bounded) and LinkedBlockingQueue (both bounded and unbounded options).

As Example put(E e) method in ArrayBlockingQueue or LinkedBlockingQueue will wait if necessary for space to become available.

Whereas put(E e) method in PriorityBlockingQueue will never block as it is unbounded.

Elements are sorted in Java PriorityBlockingQueue

The elements of the PriorityBlockingQueue are ordered according to their natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used.

Note that a priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so results in ClassCastException).

Java PriorityBlockingQueue Constructors

  • PriorityBlockingQueue()- Creates a PriorityBlockingQueue with the default initial capacity (11) that orders its elements according to their natural ordering.
  • PriorityBlockingQueue(Collection<? extends E> c)- Creates a PriorityBlockingQueue containing the elements in the specified collection.
  • PriorityBlockingQueue(int initialCapacity)- Creates a PriorityBlockingQueue with the specified initial capacity that orders its elements according to their natural ordering.
  • PriorityBlockingQueue(int initialCapacity, Comparator<? super E> comparator)- Creates a PriorityBlockingQueue with the specified initial capacity that orders its elements according to the specified comparator.

Nulls are not allowed in PriorityBlockingQueue

PriorityBlockingQueue in Java does not permit null elements. Trying to add null to the queue results in NullPointerException.

public class PriorityQDemo {
  public static void main(String[] args) {
    BlockingQueue<String> priortyBQ = new PriorityBlockingQueue<String>();
    priortyBQ.add("E");
    priortyBQ.add("B");
    priortyBQ.add("N");
    priortyBQ.add(null);
  }
}

Output

Exception in thread "main" java.lang.NullPointerException
 at java.util.concurrent.PriorityBlockingQueue.offer(PriorityBlockingQueue.java:479)
 at java.util.concurrent.PriorityBlockingQueue.add(PriorityBlockingQueue.java:463)
 at org.netjs.programs.PriorityQDemo.main(PriorityQDemo.java:13)

PriorityBlockingQueue Java example

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

public class PriorityQDemo {

  public static void main(String[] args) {
    String[] cityNames = {"Delhi", "Mumbai", "Chennai", "Bangalore", 
            "Hyderabad", "Lucknow"};
    // initializing PriortiyBlockingQueue
    BlockingQueue<String> priortyBQ = new PriorityBlockingQueue<String>();
    
    // Producer thread
    new Thread(){
      @Override
      public void run() {
        for(int i = 0; i < cityNames.length; i++){
          try {
            priortyBQ.put(cityNames[i]);
          } catch (InterruptedException e) {
            System.out.println("Error while putting values in the Queue " 
               + e.getMessage());
          }
        }
      }
    }.start();
        
    // Consumer thread
    new Thread(){
      @Override
      public void run() {
        for(int i = 0; i < cityNames.length; i++){
          try {
            System.out.println(" Consumer got - " + priortyBQ.take());
          } catch (InterruptedException e) {
            System.out.println("Error while retrieving value from the Queue " 
              + e.getMessage());
          }
        }
      }
    }.start();
  }
}

Output

Consumer got - Bangalore
Consumer got - Chennai
Consumer got - Delhi
Consumer got - Hyderabad
Consumer got - Lucknow
Consumer got - Mumbai

It can be seen here that the city names are ordered.

PriorityBlockingQueue with Comparator Java Example

You can also use a comparator, if you want different ordering than the natural ordering. Here, if you want the cities in reverse order you can use the constructor that takes comparator as parameter.

import java.util.Comparator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

public class PriorityQDemo {

  public static void main(String[] args) {
    String[] cityNames = {"Delhi", "Mumbai", "Chennai", "Bangalore", 
              "Hyderabad", "Lucknow"};
    // initializing PriortiyBlockingQueue
    BlockingQueue<String> priortyBQ = new PriorityBlockingQueue<String>(10, new CityComparator());
    
    // Producer thread
    new Thread(){
      @Override
      public void run() {
        for(int i = 0; i < cityNames.length; i++){
          try {
            priortyBQ.put(cityNames[i]);
          } catch (InterruptedException e) {
            System.out.println("Error while putting values in the Queue "
              + e.getMessage());
          }
        }
      }
    }.start();
    
    // Consumer thread
    new Thread(){
      @Override
      public void run() {
        for(int i = 0; i < cityNames.length; i++){
          try {
            System.out.println(" Consumer got - " + priortyBQ.take());
          } catch (InterruptedException e) {
            System.out.println("Error while retrieving value from the Queue " 
                + e.getMessage());
          }
        }
      }
    }.start();
  }
}

// Comparator class
class CityComparator implements Comparator<String>{
  @Override
  public int compare(String o1, String o2) {
    return o2.compareTo(o1);
  }    
}

Output

Consumer got - Mumbai
Consumer got - Lucknow
Consumer got - Hyderabad
Consumer got - Delhi
Consumer got - Chennai
Consumer got - Bangalore 

PriorityBlockingQueue Iterator

Note that though elements are stored using natural ordering, Iterator provided in method iterator() is not guaranteed to traverse the elements of the PriorityBlockingQueue in any particular order. If you need ordered traversal, consider using Arrays.sort(pq.toArray()).

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


Related Topics

  1. Java LinkedBlockingQueue With Examples
  2. Java DelayQueue With Examples
  3. Java BlockingDeque With Examples
  4. ConcurrentSkipListSet in Java With Examples
  5. Java Concurrency Interview Questions And Answers

You may also like-

  1. Thread Starvation in Java Multi-Threading
  2. Java Stream API Tutorial
  3. Serialization and Deserialization in Java
  4. Initializer Block in Java
  5. Marker Interface in Java
  6. Difference Between HashMap And ConcurrentHashMap in Java
  7. Interface Static Methods in Java
  8. Bean Scopes in Spring With Examples

Thursday, June 24, 2021

Producer-Consumer Java Program Using ArrayBlockingQueue

This Java program solves the Producer-Consumer problem using threads and ArrayBlockingQueue which is an implementation of the BlockingQueue interface.

Initial capacity of the ArrayBlockingQueue will be kept one so that producer and consumer both get a chance alternatively.

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

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

In the program there is a class Buffer which is shared by both threads. In comparison to produce-consumer using wait notify this version using blocking queue is much simpler as you don't need to write the logic for making the thread wait or notifying the waiting thread.

Producer-Consumer program in Java Using ArrayBlockingQueue

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ArrayBQDemo {
  public static void main(String[] args) {
    Buffer buffer = new Buffer();
    // Starting two threads
    ExecutorService executor = Executors.newFixedThreadPool(2);
    executor.execute(new ProdTask(buffer));
    executor.execute(new ConTask(buffer));
    executor.shutdown();
  }
}

class ProdTask implements Runnable{
  Buffer buffer;
  ProdTask(Buffer buffer){
    this.buffer = buffer;
  }
  @Override
  public void run() {
    for(int i = 0; i < 5; i++){
      buffer.put(i);
    }
  }
}

class ConTask implements Runnable{
  Buffer buffer;
  ConTask(Buffer buffer){
    this.buffer = buffer;
  }
  @Override
  public void run() {
    for(int i = 0; i < 5; i++){
      buffer.get();;
    }
  }    
}

//Shared class used by threads
class Buffer{
  int i;
  // Bouded ArrayBlockingQueue of size 1
  BlockingQueue<Integer> arrayBlockingQ = new ArrayBlockingQueue<Integer>(1);
  public void get(){
    try {
      // take method to get from blockingqueue
      System.out.println("Consumer recd - " + arrayBlockingQ.take());
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
    
  public void put(int i){
    this.i = i;
    try {
      // putting in blocking queue
      arrayBlockingQ.put(i);
      System.out.println("Putting - " + i);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}

Output

Putting - 0
Consumer recd - 0
Putting - 1
Consumer recd - 1
Putting - 2
Consumer recd - 2
Putting - 3
Consumer recd - 3
Putting - 4
Consumer recd - 4

That's all for this topic Producer-Consumer Java Program Using ArrayBlockingQueue. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Print Odd-Even Numbers Using Threads And Semaphore Java Program
  2. Java ArrayBlockingQueue With Examples
  3. How to Run Threads in Sequence in Java
  4. Setting And Getting Thread Name And Thread ID in Java
  5. Java Multithreading Interview Questions And Answers

You may also like-

  1. How to Sort Elements in Different Order in TreeSet
  2. Convert int to String in Java
  3. Connection Pooling Using Apache DBCP in Java
  4. How to Create PDF From XML Using Apache FOP
  5. Race Condition in Java Multi-Threading
  6. Abstraction in Java
  7. Interface Default Methods in Java
  8. Bean Scopes in Spring With Examples

Friday, April 9, 2021

Java SynchronousQueue With Examples

SynchronousQueue which is an implementation of the BlockingQueue interface was added in Java 5 along with other concurrent utilities like ConcurrentHashMap, ReentrantLock, Phaser, CyclicBarrier etc.

How SynchronousQueue differs from other implementations of BlockingQueue like ArrayBlockingQueue and LinkedBlockingQueue is that SynchronousQueue in Java does not have any internal capacity, not even a capacity of one. In SynchronousQueue each insert operation must wait for a corresponding remove operation by another thread, and vice versa.

What that means is, if you put an element in SynchronousQueue using put() method it will wait for another thread to receive it, you can't put any other element in the SynchronousQueue as it is blocked. Same way in case there is thread to remove an element (using take() method) but there is no element in the queue it will block and wait for an element in the queue.

Java SynchronousQueue differs in functionality

Since SynchronousQueue has a very special functionality which differs from other BlockingQueue implementations so methods in Java SynchronusQueue behave a little differently. Actually calling it a Queue itself is a bit of wrong statement as there is never more than one element present. It's more of a point-to-point handoff.

As an example take peek() method, which in other BlockingQueue implementations work as follows-

peek() - Retrieves, but does not remove, the head of this queue, or returns null if this queue is empty.

Since in SynchronousQueue an element is only present when you try to remove it so peek() method in this class always returns null.

Iterator in SynchronousQueue returns an empty iterator in which hasNext always returns false.

For purposes of other Collection methods a SynchronousQueue acts as an empty collection, so methods like

  • contains- Always returns false. A SynchronousQueue has no internal capacity.
  • remove- Always returns false. A SynchronousQueue has no internal capacity.
  • isEmpty()- Always returns true. A SynchronousQueue has no internal capacity.

Monday, March 29, 2021

Java ArrayBlockingQueue With Examples

Java ArrayBlockingQueue which is an implementation of the BlockingQueue interface was added in Java 5 along with other concurrent utilities like CopyOnWriteArrayList, ReentrantReadWriteLock, Exchanger, CountDownLatch etc.

ArrayBlockingQueue in Java is a bounded blocking queue which internally uses an array to store elements. ArrayBlockingQueue orders elements in FIFO (first-in-first-out) order. When new elements are inserted, those are inserted at the tail of the queue. At the time of retrieval, elements are retrieved from the head of the queue.

Since ArrayBlockingQueue is bounded it means you can't add unlimited number of elements in it. ArrayBlockingQueue has to be created with some initial capacity and that capacity cannot be changed later. Attempts to put an element into a full queue will result in the operation blocking; attempts to take an element from an empty queue will similarly block.

Java ArrayBlockingQueue Constructors

  1. ArrayBlockingQueue(int capacity)- Creates an ArrayBlockingQueue with the given (fixed) capacity and default access policy.
  2. ArrayBlockingQueue(int capacity, boolean fair)- Creates an ArrayBlockingQueue with the given (fixed) capacity and the specified access policy. A queue created with fairness set to true grants access to waiting producer and consumer threads in FIFO order.
  3. ArrayBlockingQueue(int capacity, boolean fair, Collection<? extends E> c)- Creates an ArrayBlockingQueue with the given (fixed) capacity, the specified access policy and initially containing the elements of the given collection, added in traversal order of the collection's iterator.

Monday, March 15, 2021

Java LinkedBlockingQueue With Examples

LinkedBlockingQueue in Java is an implementation of BlockingQueue interface. It is added in Java 5 along with other concurrent utilities like CyclicBarrier, Phaser, ConcurentHashMap, CopyOnWriteArraySet etc.

LinkedBlockingQueue in Java internally uses linked nodes to store elements. It is optionally bounded and that's where it differs from another implementation of BlockingQueue, ArrayBlockingQueue which is a bounded queue, another difference between the two is how elements are stored internally ArrayBlockingQueue uses array internally whereas LinkedBlockingQueue uses linked nodes. Since LinkedBlockingQueue is optionally bounded so it has both types of constructors

  • one where initial capacity can be passed thus making it bounded.
  • Or
  • without any capacity thus making it unbounded. Note that in case no initial capacity is defined capacity of LinkedBlockingQueue is Integer.MAX_VALUE.