DelayQueue的介绍
DelayQueue是一个延迟队列,生产者生产一个消息,或者说写入一个消息。消息存在一个被消费者消费的延迟时间。 为了让消息具有延迟的特性,DelayQueue是基于二叉堆结构实现,本质上是基于上一篇文章中的PriorityQueue实现的功能,二叉堆结构每次获取的是栈顶的数据,因此需要让DelayQueue在比较时根据延迟时间做比较。理所应当的将剩余时间最短的放在栈顶。
DelayQueue类的内容介绍
声明一个DelayQueue元素类玩一玩
/**
* @author 舒一笑
* @date 2023/6/12
*/
public class Test20 implements Delayed {
/**
* @param 任务的名称
*/
private String name;
/**
* @param 延迟时间
*/
private Long time;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getTime() {
return time;
}
public void setTime(Long time) {
this.time = time;
}
@Override
public String toString() {
return "Test20{" +
"name='" + name + '\'' +
", time=" + time +
'}';
}
/**
* @param name
* @param delay
*/
public Test20(String name, Long delay) {
this.name = name;
this.time = System.currentTimeMillis() + delay;
}
/**
* 设置队列中任务的出队时间
* @param unit the time unit
* @return
*/
@Override
public long getDelay(TimeUnit unit) {
// 时间转换方法convert
return unit.convert(time-System.currentTimeMillis(),TimeUnit.MICROSECONDS);
}
/**
* 定义消息的比较方式
* @param o the object to be compared.
* @return
*/
@Override
public int compareTo(Delayed o) {
return (int) (this.time-((Test20)o).getTime());
}
}
main方法执行
public static void main(String[] args) throws InterruptedException {
// 声明元素
Test20 element1 = new Test20("元素1",1000L);
Test20 element2 = new Test20("元素2",2000L);
Test20 element3 = new Test20("元素3",3000L);
Test20 element4 = new Test20("元素4",4000L);
Test20 element5 = new Test20("元素5",5000L);
// 声明延迟队列
DelayQueue<Test20> queue = new DelayQueue<>();
// 将元素添加到延迟队列中
queue.put(element1);
queue.put(element2);
queue.put(element3);
queue.put(element4);
queue.put(element5);
// 获取延迟队列的元素
// 输出查看结果
System.out.println("queue.take() = " + queue.take());
System.out.println("queue.take() = " + queue.take());
System.out.println("queue.take() = " + queue.take());
System.out.println("queue.take() = " + queue.take());
System.out.println("queue.take() = " + queue.take());
}
运行结果展示
应用场景介绍
在日常生活中,假如你在叮咚买菜上下一个订单。提交订单过后会有15分钟的待支付时间,要是超时未支付订单会自动取消。 这时便可以使用DelayQueue,设置15分钟延迟时间放到延迟队列中,要是在规定的时间节点内用户没有支付,直接通过消费者获取元素来取消订单。从而实现不用定时任务轮询时间的优化效果。