前言:DelayQueue延时队列是阻塞队列中的一种,想了解其他阻塞队列,点击进来学习 BlockingQueue 阻塞队列_程序员大禹的博客-CSDN博客
一、什么是DelayQueue延时队列
是一个支持延时获取元素的无界阻塞队列。队列使用PriorityQueue来实现。队列中的元素必须实现Delayed接口,在创建元素时可以指定多久才能从队列中获取当前元素。只有在延迟期满时才能从队列中提取元素。
二、使用场景
1、用户下订单后,超过一段时间未支付,订单取消
2、停车场停车超时,发送短信通知;
三、代码示例
1、定义延时对象DelayEvent,需要实现Delayed接口。
import org.springframework.stereotype.Component;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
@Component
public class DelayEvent implements java.util.concurrent.Delayed {
//任务ID
private int id;
//数据
private String data;
// 插入时间
private long startTime;
// 在队列中的保留时间
private long retainTime;
public int getId() { return id;}
public void setId(int id) {
this.id = id;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public long getStartTime() {
return startTime;
}
public void setStartTime(long startTime) {
this.startTime = startTime;
}
public long getRetainTime() {
return retainTime;
}
public void setRetainTime(long retainTime) {
this.retainTime = retainTime;
}
public DelayEvent() {}
public DelayEvent(int id, String data, long retainTime) {
this.id = id;
this.data = data;
this.startTime = System.currentTimeMillis();
this.retainTime = retainTime;
}
/**
* 判定元素是否过期, 过期时间 - 当前时间
*
* @param unit
* @return
*/
@Override
public long getDelay(TimeUnit unit) {
return unit.convert((retainTime + startTime) - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
/**
* 确定先后顺序
*
* @param o
* @return
*/
@Override
public int compareTo(Delayed o) {
DelayEvent delayEvent = (DelayEvent) o;
return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
}
}
2、测试
public class TestMain {
public static final DelayQueue<DelayEvent> queue = new DelayQueue<DelayEvent>();
public static void main(String[] args) {
//创建个线程放入任务到阻塞队列中
Thread thread = new Thread(() -> {
DelayEvent delayEvent1 = new DelayEvent(1, "任务1", 1000);
DelayEvent delayEvent2 = new DelayEvent(2, "任务2", 6000);
DelayEvent delayEvent3 = new DelayEvent(3, "任务3", 3000);
DelayEvent delayEvent5 = new DelayEvent(5, "任务5", 5000);
queue.add(delayEvent1);
queue.add(delayEvent2);
queue.add(delayEvent3);
queue.add(delayEvent5);
});
thread.start();
//从队列中取出数据
try {
while (true) {
if (queue.size() > 0) {
DelayEvent event = (DelayEvent) queue.take();
String str = JSON.toJSONString(event);
System.out.println(str);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3、执行结果
{"data":"任务1","id":1,"retainTime":1000,"startTime":1651046995180}
{"data":"任务3","id":3,"retainTime":3000,"startTime":1651046995180}
{"data":"任务5","id":5,"retainTime":5000,"startTime":1651046995180}
{"data":"任务2","id":2,"retainTime":6000,"startTime":1651046995180}
四、DelayQueue相关API
变量和类型 | 方法 | 描述 |
---|---|---|
boolean | add(E e) | 将指定的元素插入此延迟队列。 |
void | clear() | 以原子方式从此延迟队列中删除所有元素。 |
int | drainTo(Collection<? super E> c) | 从此队列中删除所有可用元素,并将它们添加到给定集合中。 |
int | drainTo(Collection<? super E> c, int maxElements) | 从该队列中删除最多给定数量的可用元素,并将它们添加到给定集合中。 |
Iterator<E> | iterator() | 返回此队列中所有元素(已过期和未过期)的迭代器。 |
boolean | offer(E e) | 将指定的元素插入此延迟队列。 |
boolean | offer(E e, long timeout, TimeUnit unit) | 将指定的元素插入此延迟队列。 |
E | peek() | 检索但不删除此队列的头部,如果此队列为空,则返回 |
E | poll() | 检索并删除此队列的头部,如果此队列没有具有过期延迟的元素,则返回 |
E | poll(long timeout, TimeUnit unit) | 检索并删除此队列的头部,必要时等待,直到此队列上具有过期延迟的元素或指定的等待时间到期为止。 |
void | put(E e) | 将指定的元素插入此延迟队列。 |
int | remainingCapacity() | 始终返回 |
boolean | remove(Object o) | 从此队列中删除指定元素的单个实例(如果存在),无论它是否已过期。 |
E | take() | 检索并删除此队列的头部,必要时等待,直到此队列上有一个具有过期延迟的元素。 |
Object[] | toArray() | 返回包含此队列中所有元素的数组。 |
<T> T[] | toArray(T[] a) | 返回包含此队列中所有元素的数组; 返回数组的运行时类型是指定数组的运行时类型。 |
版权声明:本文为ZhangXS9722原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。