java如何设计一个延时队列
时间: 2024-05-01 11:20:14 浏览: 93
Java中可以使用PriorityQueue(优先队列)和DelayQueue(延时队列)两种数据结构来实现延时队列。
DelayQueue是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,只有在延迟期满时才能从中取出对象。DelayQueue可以用于定时执行任务。
下面是一个简单的延时队列示例代码,其中使用了DelayQueue和ScheduledThreadPoolExecutor两个类:
```java
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
public class DelayQueueDemo {
public static void main(String[] args) {
DelayQueue<DelayedTask> delayQueue = new DelayQueue<>();
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2);
// 添加3个延时任务到队列中
delayQueue.put(new DelayedTask("Task 1", 5, TimeUnit.SECONDS));
delayQueue.put(new DelayedTask("Task 2", 10, TimeUnit.SECONDS));
delayQueue.put(new DelayedTask("Task 3", 15, TimeUnit.SECONDS));
// 循环从队列中取出任务并执行
while (!delayQueue.isEmpty()) {
try {
DelayedTask task = delayQueue.take();
executor.execute(task);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
executor.shutdown();
}
static class DelayedTask implements Runnable, Delayed {
private final String name;
private final long delayTime;
private final long expireTime;
public DelayedTask(String name, long delayTime, TimeUnit unit) {
this.name = name;
this.delayTime = TimeUnit.MILLISECONDS.convert(delayTime, unit);
this.expireTime = System.currentTimeMillis() + this.delayTime;
}
@Override
public int compareTo(Delayed other) {
return Long.compare(this.expireTime, ((DelayedTask) other).expireTime);
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(this.expireTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
@Override
public void run() {
System.out.println(name + " executed at " + System.currentTimeMillis());
}
}
}
```
上述代码中,我们创建了一个DelayQueue,并往其中添加了3个延时任务。每个任务都实现了Runnable和Delayed接口,其中getDelay方法返回了任务的延迟时间,compareTo方法比较了任务之间的优先级,run方法实现了具体的任务逻辑。
在主线程中,我们使用while循环从DelayQueue中取出任务并交给ScheduledThreadPoolExecutor线程池执行。当队列为空时,关闭线程池。
阅读全文