DelayQueue是什么
JDK自带DelayQueue 是一个支持延时获取元素的阻塞队列, 内部采用优先队列 PriorityQueue 存储元素,同时元素必须实现 Delayed 接口;在创建元素时可以指定多久才可以从队列中获取当前元素,只有在延迟期满时才能从队列中提取元素。
DelayQueue属于排序队列,它的特殊之处在于队列的元素必须实现Delayed接口,该接口需要实现compareTo和getDelay方法。
getDelay方法:获取元素在队列中的剩余时间,只有当剩余时间为0时元素才可以出队列。
compareTo方法:用于排序,确定元素出队列的顺序。
实现方法:
1:在测试包jdk下创建延迟任务元素对象DelayedTask,实现compareTo和getDelay方法;
2:在main方法中创建DelayQueue并向延迟队列中添加三个延迟任务;
3:循环的从延迟队列中拉取任务。
package com.dack.test;
import java.util.Calendar;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
public class DelayedTask implements Delayed {
public static DelayQueue<DelayedTask> queue;
// 任务的执行时间
private int executeTime = 0;
// 业务需要的参数
private String outStr = "";
public static void main(String[] args) {
DelayedTask.queue = new DelayQueue<DelayedTask>();
// 可有可无
DelayedTask.queue.add(new DelayedTask(2, "hello"));
System.out.println(System.currentTimeMillis() + "服务启动");
while (true) {
DelayedTask delayedTask = DelayedTask.queue.poll();
if (delayedTask != null) {
String os = delayedTask.getOutStr();
//可以随时添加新的延时任务
DelayedTask.queue.add(new DelayedTask(2, "hello"));
System.out.println(System.currentTimeMillis() + " 消费服务 ,传参" + os);
}
}
}
public DelayedTask(int delay) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, delay);
this.executeTime = (int) (calendar.getTimeInMillis());
}
// 业务所需的参数构造方法
public DelayedTask(int delay, String str) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, delay);
this.executeTime = (int) (calendar.getTimeInMillis());
this.outStr = str;
}
/**
* 元素在队列中的剩余时间
*
* @param unit
* @return
*/
@Override
public long getDelay(TimeUnit unit) {
Calendar calendar = Calendar.getInstance();
return executeTime - (calendar.getTimeInMillis());
}
/**
* 元素排序
*
* @param o
* @return
*/
@Override
public int compareTo(Delayed o) {
long val = this.getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);
return val == 0 ? 0 : (val < 0 ? -1 : 1);
}
public int getExecuteTime() {
return executeTime;
}
public void setExecuteTime(int executeTime) {
this.executeTime = executeTime;
}
public String getOutStr() {
return outStr;
}
public void setOutStr(String outStr) {
this.outStr = outStr;
}
}