DelayQueue是JDK提供的api,是一个延迟队列
DelayQueue泛型参数得实现Delayed接口,Delayed继承了Comparable接口。
getDelay
方法返回这个任务还剩多久时间可以执行,小于0的时候说明可以这个延迟任务到了执行的时间了。compareTo
这个是对任务排序的,保证最先到延迟时间的任务排到队列的头
@Data
public class DemoTask implements Delayed {
String name;
/**
* 任务关键数据
*/
List<Long> dataIds;
Long delayMillis;
public DemoTask(String name, List<Long> dataIds, Duration delaySeconds) {
this.name = name;
this.dataIds = dataIds;
this.delayMillis = System.currentTimeMillis() + delaySeconds.toMillis();
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(delayMillis -System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
return this.delayMillis.compareTo(((DemoTask) o).delayMillis);
}
}
SanYouTask实现了Delayed接口,构造参数
taskContent
:延迟任务的具体的内容delayTime
:延迟时间,秒为单位@Slf4j
public class DelayQueueDemo {
public static void main(String[] args) {
DelayQueue<DemoTask> delayQueue = new DelayQueue<>();
new Thread(() -> {
while (true) {
try {
DemoTask take = delayQueue.take();
List<Long> dataIds = take.getDataIds();
String name = take.getName();
log.info("任务名:{}", name);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}).start();
//提交任务
delayQueue.offer(new DemoTask("任务1", Arrays.asList(1L,2L), Duration.ofSeconds(3L)));
delayQueue.offer(new DemoTask("任务2", Arrays.asList(1L,2L),Duration.ofSeconds(8L)));
delayQueue.offer(new DemoTask("任务3", Arrays.asList(1L,2L),Duration.ofSeconds(10L)));
log.info("任务提交完成...");
}
}
可以看到三次任务的执行时间与我们预期的一致。分别在提交任务后的3秒/8秒/10秒开始执行
offer
方法在提交任务的时候,会通过根据compareTo的实现对任务进行排序,将最先需要被执行的任务放到队列头。
take
方法获取任务的时候,会拿到队列头部的元素,也就是队列中最早需要被执行的任务,通过getDelay返回值判断任务是否需要被立刻执行,如果需要的话,就返回任务,如果不需要就会等待这个任务到延迟时间的剩余时间,当时间到了就会将任务返回。
注意事项 :
这里的任务如果是同步,耗时较大可能回影响其他任务的准确性。所以根据实际情况考虑将任务异步化
修改任务内容,增加延时来看
new Thread(() -> {
while (true) {
try {
DemoTask take = delayQueue.take();
List<Long> dataIds = take.getDataIds();
String name = take.getName();
log.info("任务名:{}", name);
//延时10s
Thread.sleep(10000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}).start();
从上面执行结果可以看到,同步任务耗时过多会影响其他后续任务执行时间。
http://blog.xqlee.com/article/2501211614121867.html