DelayQueue是一个无界阻塞队列,可以用做延时处理,所谓延时处理就是说可以为队列中元素设定一个过期时间,其中的元素只有在时间到期时才能从中被提取。该队列的头部是延迟期满后保存时间最长的Delayed 元素。存放到DelayDeque的元素必须继承Delayed接口。Delayed接口使对象成为延迟对象,它使存放在DelayQueue类中的对象具有了激活日期。该接口强制实现下列两个方法。
- CompareTo(Delayed o) :Delayed接口继承了Comparable接口,因此有了这个方法
- getDelay(TimeUnit unit):这个方法返回到激活日期的剩余时间,时间单位由单位参数指定。
简单使用
实现一个延迟任务
public class DelayedTask implements Delayed{
/**
* 延迟时间
*/
private final long delayTime;
/**
* 到期时间
*/
private final long expire;
/**
* 数据
*/
private String data;
public DelayedTask(long delayTime,String data){
this.delayTime=delayTime;
this.data=data;
// 过期时间为:当前系统时间+延迟时间
this.expire=System.currentTimeMillis()+delayTime;
}
@Override
public long getDelay(@NotNull TimeUnit unit) {
return unit.convert(this.expire - System.currentTimeMillis() , TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(@NotNull Delayed o) {
return (int) (this.getDelay(TimeUnit.MILLISECONDS) -o.getDelay(TimeUnit.MILLISECONDS));
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("DelayedElement{");
sb.append("delay=").append(delayTime);
sb.append(", expire=").append(expire);
sb.append(", data='").append(data).append('\'');
sb.append('}');
return sb.toString();
}
}
使用延迟队列
public class DelayedQueueStudy {
public static void main(String[] args){
DelayQueue delayQueue =new DelayQueue<DelayedTask>();
DelayedTask delayedTask=new DelayedTask(5000,"abc");
DelayedTask delayedTask1=new DelayedTask(3000,"def");
delayQueue.offer(delayedTask);
delayQueue.offer(delayedTask1);
long startTime=System.currentTimeMillis();
while (true){
try {
Delayed delayedtask=delayQueue.take();
System.out.println(delayedtask);
long endTime=System.currentTimeMillis();
System.out.println("用时总时间"+(endTime-startTime));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}