DelayQueue 是一个有序无界的阻塞队列,队列中的元素不能为空,且元素在过期后才能被提取出来。如果没有过期的元素,则提取(poll())的结果为 null。
DelayQueue 中的元素必须实现 Delayed 接口,重写 getDelay(TimeUnit unit) 和 compareTo(Delayed o) 两个方法。
public static class DelayTask implements Delayed {
private int flag;
private long delayTime;
public DelayTask(int flag, long delayTime) {
this.flag = flag;
this.delayTime = delayTime;
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(delayTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
}
@Override
public String toString() {
return "DelayTask{" +
"flag=" + flag +
", delayTime=" + delayTime +
'}';
}
}
在 main 方法中,使用 DelayQueue 的 take() 方法获取和删除该队列的头部,该方法会阻塞线程直到取到可用的元素。
public static void main(String[] args) throws InterruptedException {
BlockingQueue<DelayTask> delayQueue = new DelayQueue<>();
delayQueue.put(new DelayTask(1, System.currentTimeMillis() + 1000));
delayQueue.put(new DelayTask(2, System.currentTimeMillis() + 2 * 1000));
delayQueue.put(new DelayTask(5, System.currentTimeMillis() + 5 * 1000));
delayQueue.put(new DelayTask(10, System.currentTimeMillis() + 10 * 1000));
delayQueue.put(new DelayTask(20, System.currentTimeMillis() + 20 * 1000));
for (int i = 0; i < 5; i++) {
System.out.println(delayQueue.take());
}
}
结果