March 16, 2024

DelayQueue in Java With Examples

DelayQueue in Java is an implementation of BlockingQueue interface and is part of java.util.concurrent package. DelayQueue in Java is an unbounded queue that's where it differs from ArrayBlockingQueue which is a bounded queue.

Delayed interface

Java DelayQueue can store elements only of type Delayed. There is an interface Delayed in Java which defines the type for these elements.

Delayed interface is used to define type of objects that should be acted upon after a given delay.

public interface Delayed extends Comparable<Delayed> {
  long getDelay(TimeUnit unit);
}

The getDelay(TimeUnit unit) method returns the remaining delay associated with this object, in the given time unit.

Since Delayed interface also extends Comparable interface, an implementation of this interface must define a compareTo() method that provides an ordering consistent with its getDelay method.

DelayQueue expired elements

From DelayQueue in Java an element can only be taken when its delay has expired. Element is taken from the head of the queue which means the head of the queue is that Delayed element whose delay expired furthest in the past.

Expiration of an element in the queue occurs when an element's getDelay(TimeUnit.NANOSECONDS) method returns a value less than or equal to zero.

Blocking method like take() will wait until an element with an expired delay is available on this queue.

Features of the DelayQueue in Java

  1. DelayQueue stores element of type Delayed. Interface Delayed defines the type for these Delayed elements.
  2. Element from the DelayQueue can only be taken when its delay has expired.
  3. DelayQueue is a thread-safe implementation.
  4. DelayQueue in Java does not allow null element to be added.

Java DelayQueue Constructors

  • DelayQueue()- Creates a new DelayQueue that is initially empty.
  • DelayQueue(Collection<? extends E> c)- Creates a DelayQueue initially containing the elements of the given collection of Delayed instances.

DelayQueue Java example

Here is a producer-consumer example using DelayQueue. Since DelayQueue stores element of type Delayed so we need an implementation of Delayed interface too.

  private long expiryTime;
  DelayQElement(String queueElement, long delay){
    this.queueElement = queueElement;
    // Expirytime is current time + delay
    this.expiryTime = System.currentTimeMillis() + delay;
    System.out.println("Putting queueElement "  + queueElement + " expiry " + this.expiryTime);
  }
 
  @Override
  public long getDelay(TimeUnit unit) {
    long diff = expiryTime - 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 queueElement + " Expiry Time= " + expiryTime;
  } 
}
Producer-Consumer using DelayQueue
public class DQDemo {
  public static void main(String[] args) {
    // delay of 3 seconds
    final long delay = 3000;
    BlockingQueue<DelayQElement> delayQ = new DelayQueue<DelayQElement>();
    // Producer thread
    new Thread(()->{
      for(int i = 0; i < 5; i++){
        try {
          delayQ.put(new DelayQElement("Element"+i, delay));
          Thread.sleep(50);
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }
    }).start();
        
    // Consumer thread
    new Thread(()->{
      for(int i = 0; i < 5; i++){
        try {
          System.out.println(" Consumer got - " + delayQ.take().toString());
          Thread.sleep(100);
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }
    }).start();
  }
}
Output
Putting queueElement Element0expiry 1541830388935
Putting queueElement Element1expiry 1541830388998
Putting queueElement Element2expiry 1541830389060
Putting queueElement Element3expiry 1541830389123
Putting queueElement Element4expiry 1541830389185
 Consumer got - Element0 Expiry Time= 1541830388935
 Consumer got - Element1 Expiry Time= 1541830388998
 Consumer got - Element2 Expiry Time= 1541830389060
 Consumer got - Element3 Expiry Time= 1541830389123
 Consumer got - Element4 Expiry Time= 1541830389185

As you can see the elements are taken from the queue after the element expired.

DelayQueue class methods

Here is a list of some of the methods of the DelayQueue class in Java.
  1. add(E e)- Inserts the specified element into this delay queue.
  2. clear()- Atomically removes all of the elements from this delay queue.
  3. offer(E e)- Inserts the specified element into this delay queue.
  4. peek()- Retrieves, but does not remove, the head of this queue, or returns null if this queue is empty.
  5. poll()- Retrieves and removes the head of this queue, or returns null if this queue has no elements with an expired delay.
  6. poll(long timeout, TimeUnit unit)- Retrieves and removes the head of this queue, waiting if necessary until an element with an expired delay is available on this queue, or the specified wait time expires.
  7. put(E e)- Inserts the specified element into this delay queue.
  8. remove(Object o)- Removes a single instance of the specified element from this queue, if it is present, whether or not it has expired.
  9. take()- Retrieves and removes the head of this queue, waiting if necessary until an element with an expired delay is available on this queue.

That's all for the topic DelayQueue in Java With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment