1) DelayQueue class implements the BlockingQueue interface.
The DelayQueue keeps the elements internally until a certain delay has expired.
The elements must implement the interface java.util.concurrent.Delayed.
public interface Delayed extends Comparable<Delayed> { long getDelay(TimeUnit unit); }
The value returned by the getDelay() method should be the delay remaining before this element can be released.
If 0 or a negative value is returned, the delay will be considered expired, and the element released at the next take() etc. call on the DelayQueue.
The TimeUnit instance passed to the getDelay() method is an Enum that tells which time unit the delay should be returned in.
The TimeUnit enum can take these values:
DAYS HOURS MINUTES SECONDS MILLISECONDS MICROSECONDS NANOSECONDS
The Delayed Interface also extends the java.lang.Comparable interface, as you can see, which means that Delayed objects can be compared to each other.
This is probably used internally in the DelayQueue to order the elements in the queue, so they are released ordered by their expiration time.
Example For DelayQueue:
package edu.xmu.thread; import java.util.concurrent.DelayQueue; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; public class DelayQueueTest { public static void main(String[] args) throws InterruptedException { Delayed delayedElement = new DelayedElement(10); System.out.println(delayedElement.getDelay(TimeUnit.MICROSECONDS)); DelayQueue<Delayed> delayQueue = new DelayQueue<Delayed>(); delayQueue.add(delayedElement); System.out.println(System.currentTimeMillis()); Delayed delayedElement2 = delayQueue.take(); System.out.println("delayedElement2: " + delayedElement2); System.out.println(System.currentTimeMillis()); } } class DelayedElement implements Delayed { long endTime; public DelayedElement(int delaySeconds) { super(); this.endTime = TimeUnit.NANOSECONDS.convert(delaySeconds, TimeUnit.SECONDS) + System.nanoTime(); } @Override public int compareTo(Delayed o) { return 0; } @Override public long getDelay(TimeUnit unit) { return unit.convert(endTime - System.nanoTime(), TimeUnit.NANOSECONDS); } }
Output:
9999989 1401202204613 delayedElement2: edu.xmu.thread.DelayedElement@af07c4 1401202214613
2) SynchronousQueue
1> The SynchronousQueue class implements the BlockingQueue interface.
2> The SynchronousQueue is a queue that can only contain a single element internally.
A thread inserting an element into the queue in blocked until another thread takes that element from the queue.
Likewise, if a thread tries to take an element and no element is currently present, that thread is blocked util a thread insert an element into the queue.
Calling this class a queue is a bit of an overstatement. It's more of a rendesvouz point.
package edu.xmu.thread; import java.util.concurrent.SynchronousQueue; public class SynchronousQueueTest { public static void main(String[] args) { SynchronousQueue<SynchronousData> synchronousQueue = new SynchronousQueue<SynchronousData>(); Thread producer = new Thread(new SynchronousProducerThread( synchronousQueue)); Thread producer2 = new Thread(new SynchronousProducerThread( synchronousQueue)); Thread consumer = new Thread(new SynchronousConsumerThread( synchronousQueue)); Thread consumer2 = new Thread(new SynchronousConsumerThread( synchronousQueue)); consumer.start(); consumer2.start(); producer.start(); producer2.start(); } } class SynchronousProducerThread implements Runnable { SynchronousQueue<SynchronousData> synchronousQueue; public SynchronousProducerThread( SynchronousQueue<SynchronousData> synchronousQueue) { super(); this.synchronousQueue = synchronousQueue; } @Override public void run() { while (true) { try { Thread.sleep((long) (Math.random() * 1000)); System.out.println("Thread: " + Thread.currentThread() + " is trying to put synchronousQueue"); SynchronousData synchronousData = new SynchronousData(); synchronousQueue.put(synchronousData); System.out.println("Thread: " + Thread.currentThread() + " put synchronousData: " + synchronousData); } catch (InterruptedException e) { e.printStackTrace(); } } } } class SynchronousConsumerThread implements Runnable { SynchronousQueue<SynchronousData> synchronousQueue; public SynchronousConsumerThread( SynchronousQueue<SynchronousData> synchronousQueue) { super(); this.synchronousQueue = synchronousQueue; } @Override public void run() { while (true) { try { Thread.sleep((long) (Math.random() * 1000)); System.out.println("Thread: " + Thread.currentThread() + " is trying to take from synchronousQueue"); SynchronousData synchronousData = synchronousQueue.take(); System.out.println("Thread: " + Thread.currentThread() + " got synchronousData: " + synchronousData); } catch (InterruptedException e) { e.printStackTrace(); } } } } class SynchronousData { }
Reference Links:
1) http://tutorials.jenkov.com/java-util-concurrent/delayqueue.html
2) http://tutorials.jenkov.com/java-util-concurrent/synchronousqueue.html