【JDK Collection】DelayQueue

398 阅读1分钟

DelayQueue 是一个有序无界的阻塞队列,队列中的元素不能为空,且元素在过期后才能被提取出来。如果没有过期的元素,则提取(poll())的结果为 null。

image.png

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());
    }
}

结果 image.png