DelayQueue Class in Java
In Java, the DelayQueue Class is the part of the java.util.concurrent package and implements the BlockingQueue interface. DelayQueue is a specialized implementation of a blocking queue that orders elements based on their delay time. Only elements whose delay has expired can be retrieved from the queue. If the delay has not expired, the consumer thread attempting to retrieve the element will be blocked until the delay expires.
- The queue orders elements based on their remaining delay, with the element that has the least remaining delay being the head of the queue.
- The consumer thread is blocked when trying to take elements from the queue until an element's delay has expired.
- The getDelay() method uses the TimeUnit enum(e.g. DAYS, HOURS, MINUTES, SECONDS) to specify the delay unit time.
Example: This example demonstrates how to use DelayQueue to store and execute tasks after a specified delay, processing elements as their delay times expire.
// Java Program to demonstrates the working of DelayQueue
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
public class Geeks {
// Class that implements the Delayed interface
static class MyDelayedElement implements Delayed {
private final String name;
private final long delayTime;
private final long startTime;
public MyDelayedElement(String name, long delayTime, TimeUnit unit) {
this.name = name;
// Convert delay to milliseconds
this.delayTime = unit.toMillis(delayTime);
this.startTime = System.currentTimeMillis();
}
@Override
public long getDelay(TimeUnit unit) {
long diff = startTime + delayTime - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
return Long.compare(this.getDelay(TimeUnit.MILLISECONDS),
o.getDelay(TimeUnit.MILLISECONDS));
}
public String getName() {
return name;
}
}
public static void main(String[] args) throws InterruptedException {
// Create a DelayQueue
DelayQueue<MyDelayedElement> d = new DelayQueue<>();
// Add elements with different delay times
d.add(new MyDelayedElement("Task 1", 3, TimeUnit.SECONDS));
d.add(new MyDelayedElement("Task 2", 1, TimeUnit.SECONDS));
d.add(new MyDelayedElement("Task 3", 2, TimeUnit.SECONDS));
// Wait and process elements as their delays expire
while (!d.isEmpty()) {
// This will block until an
// element's delay has expired
MyDelayedElement t = d.take();
System.out.println("Executing: " + t.getName());
}
}
}
Output:

DelayQueue Hierarchy

Declaration of DelayQueue
In Java, the declaration of DelayQueue can be done as:
public class DelayQueue<E extends Delayed> extends AbstractQueue<E> implements BlockingQueue<E>
Constructors
Constructor | Description |
---|---|
DelayQueue() | This constructor is used to construct an empty DelayQueue. |
DelayQueue(Collection<E> c) | This constructor is used to construct a DelayQueue with the elements of the Collection of Delayed instances passed as the parameter. |
Example: This example demonstrates how the DelayQueue holds elements and only allows them to be retrieved after their specified delay time has expired.
// Java program to demonstrates
// how DelayQueue holds elements
import java.util.concurrent.*;
import java.util.*;
// The DelayObject for DelayQueue
// It must implement Delayed and
// its getDelay() and compareTo() method
class DelayObject implements Delayed {
private String name;
private long time;
// Constructor of DelayObject
public DelayObject(String name, long delayTime) {
this.name = name;
this.time = System.currentTimeMillis() + delayTime;
}
// Implementing getDelay() method of Delayed
@Override
public long getDelay(TimeUnit unit) {
long diff = time - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
// Implementing compareTo() method of Delayed
@Override
public int compareTo(Delayed obj) {
if (this.time < ((DelayObject) obj).time) {
return -1;
}
if (this.time > ((DelayObject) obj).time) {
return 1;
}
return 0;
}
// Implementing toString() method of Delayed
@Override
public String toString() {
return "{name=" + name + ", time=" + time + "}";
}
}
// Driver Class
public class Geeks {
public static void main(String[] args) throws InterruptedException {
// Create object of DelayQueue
// using DelayQueue() constructor
BlockingQueue<DelayObject> d = new DelayQueue<DelayObject>();
// Add numbers to the end of DelayQueue
// with different delays
d.add(new DelayObject("A", 1000));
d.add(new DelayObject("B", 2000));
d.add(new DelayObject("C", 3000));
d.add(new DelayObject("D", 4000));
// Print DelayQueue (before delays have expired)
System.out.println("Initial DelayQueue: " + d);
// Polling and taking elements after their delay has expired
// Poll until queue is empty, with a timeout of 1 second
while (!d.isEmpty()) {
// Take will block until an element's delay expires
// This will block until an element becomes available
DelayObject obj = d.take();
System.out.println("Taken from DelayQueue: " + obj);
}
}
}
Output:

Performing Various Operations on DelayQueue
1. Adding Elements: We can use add() method to insert elements in the DelayQueue.
Example: This example demonstrates how to add custom DelayedQueue and check the size of the queue.
// Adding elements in DelayQueue
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
class MyDelayedObject implements Delayed {
private String name;
private long time;
public MyDelayedObject(String name, long delayTime)
{
this.name = name;
this.time = System.currentTimeMillis() + delayTime;
}
@Override public long getDelay(TimeUnit unit)
{
long diff = time - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
@Override public int compareTo(Delayed o)
{
return Long.compare(this.time,
((MyDelayedObject)o).time);
}
}
public class Geeks {
public static void main(String args[])
{
DelayQueue<Delayed> q = new DelayQueue<>();
// Add a MyDelayedObject with a delay of 2 seconds
q.add(new MyDelayedObject("Task1", 2000));
// Printing the size of the queue
System.out.println("Size of the queue: "
+ q.size());
}
}
Output
Size of the queue: 1
2. Removing Elements: We can use the remove() method to remove elements from a DelayQueue.
Example: This example demonstrates how to use the remove() method to remove a specified element from the Queue.
// Removing elements in DelayQueue
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
public class Geeks {
public static void main(String args[])
{
// Create a DelayQueue instance
DelayQueue<Delayed> q = new DelayQueue<Delayed>();
// Create an object of type Delayed
Delayed ob = new Delayed() {
public long getDelay(TimeUnit unit)
{
return 24; // some value is returned
}
public int compareTo(Delayed o)
{
if (o.getDelay(TimeUnit.DAYS)
> this.getDelay(TimeUnit.DAYS))
return 1;
else if (o.getDelay(TimeUnit.DAYS)
== this.getDelay(TimeUnit.DAYS))
return 0;
return -1;
}
};
// Add the object to DelayQueue
q.add(ob);
// Print initial size of Queue
System.out.println("Initial Size of DelayQueue : "
+ q.size());
// Remove the object ob from
// this DelayQueue
q.remove(ob);
// Print the final size of the DelayQueue
System.out.println("Size after removal : " + q.size());
}
}
Output
Initial Size of DelayQueue : 1 Size after removal : 0
3. Accessing Elements: We can use the peek() method to retrieve the head of the DelayQueue without removing it.
Example: This example demonstrates how to access the head of the queue using the peek() method without removing it.
// Accessing elements in DelayQueue
import java.util.concurrent.*;
import java.util.*;
// The DelayObject for DelayQueue
// It must implement Delayed and
// its getDelay() and compareTo() method
class DelayObject implements Delayed {
private String name;
private long time;
// Constructor of DelayObject
public DelayObject(String name, long delayTime)
{
this.name = name;
this.time = System.currentTimeMillis() + delayTime;
}
// Implementing getDelay() method of Delayed
@Override
public long getDelay(TimeUnit unit)
{
long diff = time - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
// Implementing compareTo() method of Delayed
@Override
public int compareTo(Delayed obj)
{
if (this.time < ((DelayObject)obj).time) {
return -1;
}
if (this.time > ((DelayObject)obj).time) {
return 1;
}
return 0;
}
// Implementing toString() method of Delayed
@Override
public String toString()
{
return "\n{" + name + ", time=" + time + "}";
}
}
// Driver Class
public class Geeks {
public static void main(String[] args)
throws InterruptedException
{
// create object of DelayQueue
// using DelayQueue() constructor
BlockingQueue<DelayObject> d = new DelayQueue<DelayObject>();
// Add numbers to end of DelayQueue
// using add() method
d.add(new DelayObject("A", 1000));
d.add(new DelayObject("B", 2000));
// Print DelayQueue
System.out.println("Original DelayQueue: " + d);
// peek() method for returning head of the
// DelayQueue
System.out.println("Head of the DelayQueue: " + d.peek());
}
}
Output
Original DelayQueue: [ {A, time=1740118931434}, {B, time=1740118932434}] Head of the DelayQueue: {A, time=1740118931434}
4. Iterating Elements: We can use the iterator() method of DelayQueue which return an iterator that allows traversing through the elements of the queue.
Example: This example demonstrates how to iterate over a DelayQueue and print its elements without removing them.
// Iterating elements in DelayQueue
import java.util.concurrent.*;
import java.util.*;
class DelayObject implements Delayed {
private String name;
private long time;
// Constructor of DelayObject
public DelayObject(String name, long delayTime) {
this.name = name;
this.time = System.currentTimeMillis() + delayTime;
}
// Implementing getDelay() method of Delayed
@Override
public long getDelay(TimeUnit unit) {
long diff = time - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
// Implementing compareTo() method of Delayed
@Override
public int compareTo(Delayed obj) {
if (this.time < ((DelayObject)obj).time) {
return -1;
}
if (this.time > ((DelayObject)obj).time) {
return 1;
}
return 0;
}
// Implementing toString() method of Delayed
@Override
public String toString() {
return "\n{" + name + ", time=" + time + "}";
}
}
public class Geeks {
public static void main(String[] args) throws InterruptedException {
// create object of DelayQueue
BlockingQueue<DelayObject> d = new DelayQueue<DelayObject>();
// Add numbers to end of DelayQueue
d.add(new DelayObject("A", 1));
d.add(new DelayObject("B", 2));
d.add(new DelayObject("C", 3));
d.add(new DelayObject("D", 4));
// Creating an iterator
Iterator<DelayObject> i = d.iterator();
// Print the value after iterating over DelayQueue
System.out.println("The iterator values are: ");
while (i.hasNext()) {
System.out.println(i.next());
}
}
}
Output
The iterator values are: {A, time=1740119064135} {B, time=1740119064136} {C, time=1740119064137} {D, time=1740119064138}
Methods
Methods | Description |
---|---|
add(E e) | Inserts the specified element into this delay queue. |
clear() | Atomically removes all of the elements from this delay queue. |
drainTo(Collection<? super E> c) | Removes all available elements from this queue and adds them to the given collection. |
drainTo(Collection<? super E> c, int maxElements) | Removes at most the given number of available elements from this queue and adds them to the given collection. |
iterator() | Returns an iterator over all the elements (both expired and unexpired) in this queue. |
offer(E e) | Inserts the specified element into this delay queue. |
offer(E e, long timeout, TimeUnit unit) | Inserts the specified element into this delay queue. |
peek() | Retrieves, but does not remove, the head of this queue, or returns null if this queue is empty. |
poll() | Retrieves and removes the head of this queue, or returns null if this queue has no elements with an expired delay. |
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. |
put(E e) | Inserts the specified element into this delay queue. |
remainingCapacity() | Always returns Integer.MAX_VALUE because a DelayQueue is not capacity constrained. |
remove(Object o) | Removes a single instance of the specified element from this queue, if it is present, whether or not it has expired. |
take() | Retrieves and removes the head of this queue, waiting if necessary until an element with an expired delay is available on this queue. |
toArray() | Returns an array containing all of the elements in this queue. |
toArray(T[] a) | Returns an array containing all of the elements in this queue; the runtime type of the returned array is that of the specified array. |
Methods Declared in Class java.util.AbstractQueue
Methods | Description |
---|---|
addAll(Collection<? extends E> c) | Adds all of the elements in the specified collection to this queue. |
element() | Retrieves, but does not remove, the head of this queue. |
remove() | Retrieves and removes the head of this queue. |
Methods Declared in Class java.util.AbstractCollection
Methods | Description |
---|---|
contains(Object o) | Returns true if this collection contains the specified element. |
containsAll(Collection<?> c) | Returns true if this collection contains all of the elements in the specified collection. |
isEmpty() | Returns true if this collection contains no elements. |
removeAll(Collection<?> c) | Removes all of this collection's elements that are also contained in the specified collection (optional operation). |
retainAll(Collection<?> c) | Retains only the elements in this collection that are contained in the specified collection (optional operation). |
toString() | Returns a string representation of this collection. |
Method Declared in Interface java.util.concurrent.BlockingQueue
Methods | Description |
---|---|
contains(Object o) | Returns true if this queue contains the specified element. |
Methods Declared in Interface java.util.Collection
Methods | Description |
---|---|
addAll(Collection<? extends E> c) | Adds all of the elements in the specified collection to this collection (optional operation). |
containsAll(Collection<?> c) | Returns true if this collection contains all of the elements in the specified collection. |
equals(Object o) | Compares the specified object with this collection for equality. |
hashCode() | Returns the hash code value for this collection. |
isEmpty() | Returns true if this collection contains no elements. |
parallelStream() | Returns a possibly parallel Stream with this collection as its source. |
removeAll(Collection<?> c) | Removes all of this collection's elements that are also contained in the specified collection (optional operation). |
removeIf(Predicate<? super E> filter) | Removes all of the elements of this collection that satisfy the given predicate. |
retainAll(Collection<?> c) | Retains only the elements in this collection that are contained in the specified collection (optional operation). |
size() | Returns the number of elements in this collection. |
spliterator() | Creates a Spliterator over the elements in this collection. |
stream() | Returns a sequential Stream with this collection as its source. |
toArray(IntFunction<T[]> generator) | Returns an array containing all of the elements in this collection, using the provided generator function to allocate the returned array. |
Method Declared in Interface java.lang.Iterable
Methods | Description |
---|---|
forEach(Consumer<? super T> action) | Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception. |
Methods Declared in Interface java.util.Queue
Methods | Description |
---|---|
element() | Retrieves, but does not remove, the head of this queue. |
remove() | Retrieves and removes the head of this queue. |
Example: This example demonstrates how to use various methods of the DelayQueue including adding elements, retrieving the head of the queue, checking its size, removing the head, and clearing the queue.
// Java Program Demonstrate DelayQueue methods
import java.util.concurrent.*;
import java.util.*;
// The DelayObject for DelayQueue
// It must implement Delayed and
// its getDelay() and compareTo() method
class DelayObject implements Delayed {
private String name;
private long time;
// Constructor of DelayObject
public DelayObject(String name, long delayTime)
{
this.name = name;
this.time = System.currentTimeMillis()
+ delayTime;
}
// Implementing getDelay() method of Delayed
@Override
public long getDelay(TimeUnit unit)
{
long diff = time - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
// Implementing compareTo() method of Delayed
@Override
public int compareTo(Delayed obj)
{
if (this.time < ((DelayObject)obj).time) {
return -1;
}
if (this.time > ((DelayObject)obj).time) {
return 1;
}
return 0;
}
// Implementing toString()
// method of Delayed
@Override
public String toString()
{
return "\n{"
+ "name=" + name
+ ", time=" + time
+ "}";
}
}
// Driver Class
public class Geeks {
public static void main(String[] args)
throws InterruptedException
{
// create object of DelayQueue
// using DelayQueue() constructor
BlockingQueue<DelayObject> d
= new DelayQueue<DelayObject>();
// Add numbers to end of DelayQueue
// using add() method
d.add(new DelayObject("A", 1));
d.add(new DelayObject("B", 2));
d.add(new DelayObject("C", 3));
d.add(new DelayObject("D", 4));
// print queue
System.out.println("DelayQueue: "
+ d);
// print the head using peek() method
System.out.println("Head of DelayQueue: "
+ d.peek());
// print the size using size() method
System.out.println("Size of DelayQueue: "
+ d.size());
// remove the head using poll() method
System.out.println("Head of DelayQueue: "
+ d.poll());
// print the size using size() method
System.out.println("Size of DelayQueue: "
+ d.size());
// clear the DelayQueue using clear() method
d.clear();
System.out.println("Size of DelayQueue"
+ " after clear: "
+ d.size());
}
}
Output:
