Quantcast
Channel: Tech Tutorials
Viewing all articles
Browse latest Browse all 862

DelayQueue in Java Concurrency

$
0
0

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 DelayQueue in Java Concurrency. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. SynchronousQueue in Java
  2. BlockingDeque in Java Concurrency
  3. LinkedTransferQueue in Java
  4. ReentrantReadWriteLock in Java
  5. Semaphore in Java Concurrency

You may also like-

  1. ConcurrentHashMap in Java
  2. Deadlock in Java multi-threading
  3. Synchronization in Java multithreading
  4. Java Collections Interview Questions
  5. Lambda expression and variable scope
  6. Autowiring using annotations in Spring
  7. try-with-resources in Java 7
  8. How to Find The Longest Palindrome in The Given String

Viewing all articles
Browse latest Browse all 862

Trending Articles