当前位置 : 主页 > 编程语言 > java >

Java并发之的DelayQueue简单介绍和使用

来源:互联网 收集:自由互联 发布时间:2022-07-05
概念 DelayQueue是一个支持延时获取元素的无界阻塞队列。队列使用PriorityQueue来实现。队列中的元素必须实现Delayed接口,在创建元素时可以指定多久才能从队列中获取当前元素。只有在延

概念

DelayQueue是一个支持延时获取元素的无界阻塞队列。队列使用PriorityQueue来实现。队列中的元素必须实现Delayed接口,在创建元素时可以指定多久才能从队列中获取当前元素。只有在延迟期满时才能从队列中提取元素。

队列的头部,是延迟期满后保存时间最长的delay元素,是最接近过期的元素。没有过期元素的话,使用poll()方法会返回null值

使用场景

DelayQueue非常有用,可以将DelayQueue运用在以下应用场景。

  • 缓存系统的设计:可以用DelayQueue保存缓存元素的有效期,使用一个线程循环查询DelayQueue,一旦能从DelayQueue中获取元素时,表示缓存有效期到了。还有订单到期,限时支付等等
  • 定时任务调度:使用DelayQueue保存当天将会执行的任务和执行时间,一旦从DelayQueue中获取到任务就开始执行,比如TimerQueue就是使用DelayQueue实现的。
  • 使用条件

    存放DelayQueue的元素,必须继承Delay接口,Delay接口使对象成为延迟对象。

    该接口强制实现两个方法:

  • CompareTo(Delayed o):用于比较延时,队列里元素的排序依据,这个是Comparable接口的方法,因为Delay实现了Comparable接口,所以需要实现。
  • getDelay(TimeUnit unit):这个接口返回到激活日期的–剩余时间,时间单位由单位参数指定。
  • 此队列不允许使用null元素。

    简单源码介绍

    ​​https://www.jianshu.com/p/6c3d5c7a386d​​

    代码

    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.concurrent.DelayQueue;
    import java.util.concurrent.Delayed;
    import java.util.concurrent.TimeUnit;

    public class DelayQueueDemo {
    public static void main(String[] args) {
    DelayQueue<DelayTask> queue = new DelayQueue<DelayTask>();
    //TODO 放数据
    queue.add(new DelayTask("order1", new Date()));//第一个元素,时间放当前时间(放进去就可以出来)。
    //第2个元素,时间放当前时间+5秒(放进去5秒就可以出来)。
    queue.add(new DelayTask("order2-5s", new Date(System.currentTimeMillis()+5000)));
    //第3个元素,时间放当前时间+10秒(放进去10秒就可以出来)。
    queue.add(new DelayTask("order3-10s", new Date(System.currentTimeMillis()+10000)));

    System.out.println("queue put done");

    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
    //TODO 无限循环。取数据
    while(!queue.isEmpty()) {
    try {
    DelayTask task = queue.take();
    System.out.println(task.name + ":" +df.format(new Date(System.currentTimeMillis())) );

    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    //存放到DelayDeque的元素必须实现Delayed接口
    static class DelayTask implements Delayed {
    private String name;
    private Date taskTime;

    public DelayTask(String name, Date taskTime) {
    this.name = name;
    this.taskTime = taskTime;
    }
    //TODO 延迟任务是否到时
    @Override
    public long getDelay(TimeUnit unit) {
    return unit.convert(taskTime.getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
    }
    //TODO 排序
    @Override
    public int compareTo(Delayed o) {
    DelayTask delayTask = (DelayTask) o;
    long diff = taskTime.getTime() - delayTask.getTaskTime().getTime();
    if (diff > 0) {
    return 1;
    } else if (diff == 0) {
    return 0;
    } else {
    return -1;
    }
    }
    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public Date getTaskTime() {
    return taskTime;
    }

    public void setTaskTime(Date taskTime) {
    this.taskTime = taskTime;
    }
    }
    }

    执行后打印的效果

    queue put done
    order1:2021-04-22 12:31:06
    order2-5s:2021-04-22 12:31:11
    order3-10s:2021-04-22 12:31:16


    上一篇:Java校验字符串是否包含空格
    下一篇:没有了
    网友评论