文章目录
引言
DelayQueue是Java并发包中一个专门用于延迟处理的阻塞队列实现,它根据延迟时间对元素进行排序,只有当元素的延迟时间到期时才能被获取。DelayQueue在任务调度、消息延迟投递等场景中发挥着重要作用。
一、DelayQueue工作原理
DelayQueue的核心是基于PriorityQueue实现的优先级队列,并结合了线程安全机制。队列中的元素必须实现Delayed接口,以支持延迟特性和优先级排序。
import java.util.concurrent.*;
public class DelayQueueExample {
// 实现Delayed接口的延迟任务
static class DelayedTask implements Delayed {
private final String name;
private final long startTime;
public DelayedTask(String name, long delayInMillis) {
this.name = name;
this.startTime = System.currentTimeMillis() + delayInMillis;
}
@Override
public long getDelay(TimeUnit unit) {
// 计算剩余延迟时间
long diff = startTime - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed other) {
// 按照延迟时间排序
return Long.compare(getDelay(TimeUnit.MILLISECONDS),
other.getDelay(TimeUnit.MILLISECONDS));
}
}
}
二、延迟队列的内部实现
DelayQueue通过巧妙地结合ReentrantLock和Condition实现了线程安全和阻塞特性。它的内部实现确保了元素按照延迟时间顺序被处理。
public class CustomDelayQueue<E extends Delayed> {
private final PriorityQueue<E> queue;
private final ReentrantLock lock;
private final Condition available;
public CustomDelayQueue() {
queue = new PriorityQueue<>();
lock = new ReentrantLock();
available = lock.newCondition();
}
public void put(E element) {
lock.lock();
try {
queue.offer(element);
if (queue.peek() == element) {
available.signal();
}
} finally {
lock.unlock();
}
}
public E take() throws InterruptedException {
lock.lockInterruptibly();
try {
for (;;) {
E first = queue.peek();
if (first == null) {
available.await();
continue;
}
long delay = first.getDelay(TimeUnit.NANOSECONDS);
if (delay <= 0) {
return queue.poll();
}
available.awaitNanos(delay);
}
} finally {
lock.unlock();
}
}
}
三、高级特性与优化
3.1 优先级控制
除了基本的延迟功能,DelayQueue还可以实现更复杂的优先级控制机制。
public class PriorityDelayQueue {
static class PriorityTask implements Delayed {
private final String name;
private final long time;
private final int priority;
public PriorityTask(String name, long delay, int priority) {
this.name = name;
this.time = System.currentTimeMillis()