JDK 自带的延迟队列
- DelayQueue
- JDK自带DelayQueue 是一个支持延时获取元素的阻塞队列, 内部采用优先队列 PriorityQueue 存储元素,
- 同时元素必须实现 Delayed 接口;在创建元素时可以指定多久才可以从队列中获取当前元素,只有在延迟期满时才能从队列中提取元素
- DelayQueue属于排序队列,它的特殊之处在于队列的元素必须实现Delayed接口,该接口需要实现compareTo和getDelay方法
- getDelay方法:获取元素在队列中的剩余时间,只有当剩余时间为0时元素才可以出队列。
- compareTo方法:用于排序,确定元素出队列的顺序。
- 实现:
- 1:在测试包jdk下创建延迟任务元素对象DelayedTask,实现compareTo和getDelay方法,
- 2:在main方法中创建DelayQueue并向延迟队列中添加三个延迟任务,
- 3:循环的从延迟队列中拉取任务
![在这里插入图片描述](https://img-blog.csdnimg.cn/45ac2531712248c4be15110d5fa4a6b9.png)
import java.util.Calendar;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import java.util.spi.CalendarDataProvider;
/**
* JDK 自带的 延迟队列
* DelayQueue
* JDK自带DelayQueue 是一个支持延时获取元素的阻塞队列, 内部采用优先队列 PriorityQueue 存储元素,
* 同时元素必须实现 Delayed 接口;在创建元素时可以指定多久才可以从队列中获取当前元素,只有在延迟期满时才能从队列中提取元素
*
* DelayQueue属于排序队列,它的特殊之处在于队列的元素必须实现Delayed接口,该接口需要实现compareTo和getDelay方法
* getDelay方法:获取元素在队列中的剩余时间,只有当剩余时间为0时元素才可以出队列。
* compareTo方法:用于排序,确定元素出队列的顺序。
* 实现:
* 1:在测试包jdk下创建延迟任务元素对象DelayedTask,实现compareTo和getDelay方法,
* 2:在main方法中创建DelayQueue并向延迟队列中添加三个延迟任务,
* 3:循环的从延迟队列中拉取任务
*/
public class DelayedTask implements Delayed {
// 任务的执行时间
private int executeTime = 0;
/**
* Second 秒
* TimeInMillis 毫秒
* @param delay
*/
public DelayedTask(int delay) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND,delay);
this.executeTime = (int)(calendar.getTimeInMillis()/1000);
}
/**
* getDelay方法:获取元素在队列中的剩余时间,只有当剩余时间为0时元素才可以出队列。
* 元素在队列中的剩余时间
* @param unit
* @return
*/
@Override
public long getDelay(TimeUnit unit) {
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.getTimeInMillis()/1000);
return executeTime-(calendar.getTimeInMillis()/1000);
}
/**
* compareTo方法:用于排序,确定元素出队列的顺序。
* 元素排序
* @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 static void main(String[] args) {
DelayQueue<DelayedTask> queue = new DelayQueue<>();
queue.add(new DelayedTask(5));
queue.add(new DelayedTask(15));
queue.add(new DelayedTask(10));
System.out.println(System.currentTimeMillis()/100+"start consume");
while (queue.size()!=0){
DelayedTask delayedTask = queue.poll();
if (delayedTask!=null){
System.out.println(System.currentTimeMillis()/100+"start consume task");
}
//每隔一秒消费一次
try{
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}