概念 DelayQueue是一个支持延时获取元素的无界阻塞队列。队列使用PriorityQueue来实现。队列中的元素必须实现Delayed接口,在创建元素时可以指定多久才能从队列中获取当前元素。只有在延
概念
DelayQueue是一个支持延时获取元素的无界阻塞队列。队列使用PriorityQueue来实现。队列中的元素必须实现Delayed接口,在创建元素时可以指定多久才能从队列中获取当前元素。只有在延迟期满时才能从队列中提取元素。
队列的头部,是延迟期满后保存时间最长的delay元素,是最接近过期的元素。没有过期元素的话,使用poll()方法会返回null值
使用场景
DelayQueue非常有用,可以将DelayQueue运用在以下应用场景。
使用条件
存放DelayQueue的元素,必须继承Delay接口,Delay接口使对象成为延迟对象。
该接口强制实现两个方法:
此队列不允许使用null元素。
简单源码介绍
https://www.jianshu.com/p/6c3d5c7a386d
代码
import java.text.SimpleDateFormat;import java.util.Date;
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<DelayTask> queue = new DelayQueue<DelayTask>();
//TODO 放数据
queue.add(new DelayTask("order1", new Date()));//第一个元素,时间放当前时间(放进去就可以出来)。
//第2个元素,时间放当前时间+5秒(放进去5秒就可以出来)。
queue.add(new DelayTask("order2-5s", new Date(System.currentTimeMillis()+5000)));
//第3个元素,时间放当前时间+10秒(放进去10秒就可以出来)。
queue.add(new DelayTask("order3-10s", new Date(System.currentTimeMillis()+10000)));
System.out.println("queue put done");
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
//TODO 无限循环。取数据
while(!queue.isEmpty()) {
try {
DelayTask task = queue.take();
System.out.println(task.name + ":" +df.format(new Date(System.currentTimeMillis())) );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//存放到DelayDeque的元素必须实现Delayed接口
static class DelayTask implements Delayed {
private String name;
private Date taskTime;
public DelayTask(String name, Date taskTime) {
this.name = name;
this.taskTime = taskTime;
}
//TODO 延迟任务是否到时
public long getDelay(TimeUnit unit) {
return unit.convert(taskTime.getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
//TODO 排序
public int compareTo(Delayed o) {
DelayTask delayTask = (DelayTask) o;
long diff = taskTime.getTime() - delayTask.getTaskTime().getTime();
if (diff > 0) {
return 1;
} else if (diff == 0) {
return 0;
} else {
return -1;
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getTaskTime() {
return taskTime;
}
public void setTaskTime(Date taskTime) {
this.taskTime = taskTime;
}
}
}
执行后打印的效果
queue put doneorder1:2021-04-22 12:31:06
order2-5s:2021-04-22 12:31:11
order3-10s:2021-04-22 12:31:16