DelayQueue:延时队列,首先是一个队列,所以可以持有对象,但是仅限于实现了Delayed接口的对象。重写getDelay()和compareTo()(因为要比较)方法;
通俗来讲;延时队列的就是个容器,可以向内添加一个个任务,每次拿出来都是最紧急的任务。
打个比方:延时队列好似一个背包,一个个定时炸弹(线程)被开启放进入,每次掏出来的都是马上要爆炸的💣(最紧急的任务)。
延时队列通过任务的compareTo()方法来排序。
下面是从《Think in Java》中简化的例子:
package com.houjun.newClassBank;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class DelayQueueDemo {
public static void main(String[] args) throws InterruptedException {
Random random = new Random();
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
DelayQueue<DelayedTask> delayQueue = new DelayQueue<DelayedTask>();
for (int i = 0; i < 20; i++) {
int delay = random.nextInt(5000);
System.out.println(delay);
delayQueue.put(new DelayedTask(delay));// 向延时队列中加入任务
}
DelayedTaskConsumer delayedTaskConsumer = new DelayedTaskConsumer(delayQueue);
TimeUnit.SECONDS.sleep(5);
newCachedThreadPool.execute(delayedTaskConsumer);
}
}
class DelayedTask implements Runnable, Delayed {
private static int counter = 0;
private final int id = counter++;
private final int delta;
private final long trigger;
protected static List<DelayedTask> sequence = new ArrayList<DelayedTask>();
public DelayedTask(int delta) {
this.delta = delta;
this.trigger = System.nanoTime() + TimeUnit.NANOSECONDS.convert(delta, TimeUnit.MILLISECONDS);
sequence.add(this);
}
@Override
public int compareTo(Delayed o) {
DelayedTask that = (DelayedTask) o;
if (this.trigger < that.trigger) {
return -1;
}
if (this.trigger > that.trigger) {
return 1;
}
return 0;
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(trigger - System.nanoTime(), TimeUnit.NANOSECONDS);
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(this + " ");
}
@Override
public String toString() {
return String.format("[%1$-4d]", delta) + " Task " + id;
}
public String summary() {
return "(" + id + ":" + delta + ")";
}
/*
* public static class EndSentinel extends DelayedTask{
*
* private ExecutorService executorService; public EndSentinel(int delay,
* ExecutorService executorService) { super(delay); executorService =
* executorService; }
*
*
* }
*/
}
class DelayedTaskConsumer implements Runnable {
private DelayQueue<DelayedTask> q;
public DelayedTaskConsumer(DelayQueue<DelayedTask> q) {
this.q = q;
}
@Override
public void run() {
while(!Thread.interrupted()) {
DelayedTask delayedTask;
try {
delayedTask = q.take();// 取出到期的任务
delayedTask.run();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}
}