Java SE: Concurrency Utils DelayQueue

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

 

你可能感兴趣的:(java,DelayQueue)