简介
DelayQueue是一个无界的BlockingQueue,只有在延迟期满时才能从中提取元素。为了具有调用行为,存放到DelayDeque的元素必须继承Delayed接口。Delayed接口使对象成为延迟对象,它使存放在DelayQueue类中的对象具有了激活日期。该接口强制执行下列两个方法。
- CompareTo(Delayed o):Delayed接口继承了Comparable接口,因此有了这个方法。
- getDelay(TimeUnit unit):这个方法返回到激活日期的剩余时间,时间单位由单位参数指定。
方法
添加的方法:add put
1.add:将指定的元素插入此延迟队列,添加成功返回true,添加null值会抛NullPointerException
2.put:将指定的元素插入此延迟队列。由于队列是无限制的,因此该方法永远不会阻塞。
获取元素的方法
1.poll:检索并删除此队列的头部,没有则返回null。
2.take:检索并删除此队列的头部,必要时等待,直到此队列上有一个具有过期延迟的元素。
实例
共享实例变量
public class DelayQueueFactory {
public static DelayQueue<QrCodeOrderQueryQueue> delayQueue = new DelayQueue<>();
public static void product(QrCodeOrderQueryQueue qrCodeOrderQueryQueue){
delayQueue.put(qrCodeOrderQueryQueue);
System.out.println("product:"+ qrCodeOrderQueryQueue.getDelayTimeMin());
}
public static QrCodeOrderQueryQueue consumer() throws InterruptedException {
QrCodeOrderQueryQueue take = delayQueue.take();
System.out.println("consumer:" + take);
return take;
}
}
定义queue实现Delayed接口
public class QrCodeOrderQueryQueue implements Delayed{
private static final Logger log = LoggerFactory.getLogger(QrCodeOrderQueryQueue.class);
private Integer delayTimeMin;
private long executeTime;
public String paramsJson;
public QrCodeOrderQueryQueue() {
}
public QrCodeOrderQueryQueue(Integer delayTimeMin, String paramsJson) {
this.delayTimeMin = delayTimeMin;
this.executeTime = getExecuteTime(delayTimeMin);
this.paramsJson = paramsJson;
}
private long getExecuteTime(Integer delayTimeMin) {
long executeTime = (delayTimeMin == null ? 0 : delayTimeMin * 1000) + System.currentTimeMillis();
return executeTime;
}
//延迟执行的时间
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(executeTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
if (this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)) {
return 1;
} else if (this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)) {
return -1;
}
return 0;
}
public Integer getDelayTimeMin() {
return delayTimeMin;
}
public void setDelayTimeMin(Integer delayTimeMin) {
this.delayTimeMin = delayTimeMin;
}
public long getExecuteTime() {
return executeTime;
}
public void setExecuteTime(long executeTime) {
this.executeTime = executeTime;
}
public String getParamsJson() {
return paramsJson;
}
public void setParamsJson(String paramsJson) {
this.paramsJson = paramsJson;
}
}
消费者
public class Consumer implements Runnable{
public Consumer(){
}
@Override
public void run() {
while(true){
try {
QrCodeOrderQueryQueue queue = DelayQueueFactory.consumer();
//去执行订单查询
String paramsJson = queue.getParamsJson();
System.out.println("执行订单查询:" + paramsJson);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
测试
public class TestDelayQueue {
public static void main(String[] args){
ExecutorService executorService = Executors.newCachedThreadPool();
//生产者去生产
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 1000; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
DelayQueueFactory.product(new QrCodeOrderQueryQueue(3, "{\"order_no\": \"123456\"}" + "--->" + i));
}
}
}).start();
//消费者去消费
Consumer consumer = new Consumer();
executorService.execute(consumer);
}
}
注意:此种方法项目重启的话,队列汇总的数据会消失