简介

DelayQueue 是一种延时阻塞队列,向队列提交一个任务,并给任务设置一定的延时时间,那么一定要等到该时间过后,才可以消费队列的元素。

使用

打开源码,发现该队列的泛型只能是一种实现了Delayed接口的类

Delayed接口如下图

可以看出,该接口继承了Comparable,那么子类必须实现 compareTo 方法,以及自带的一个抽象方法getDelay。

getDelay:返回与此对象相关的剩余延迟时间,以给定的时间单位表示
compareTo:根据这个方法来做排序

我们在idea中,输入快捷键:ctrl + H 查看该类的所有实现类。然后挑几个类作为参考。

类DelayedTimer是一个不错的参考。

private static long now() {  return System.nanoTime() - NANO_ORIGIN;
}static class DelayedTimer implements Delayed {  // most of it copied from  // java.util.concurrent.ScheduledThreadPoolExecutor  /**  * Sequence number to break scheduling ties, and in turn to     * guarantee FIFO order among tied entries.     */    private static final AtomicLong sequencer = new AtomicLong(0);  /** Sequence number to break ties FIFO */  //不太理解,根据compareTo的方法,不也是先进先出吗,先创建的任务排在队列的前面,为什么说打破了FIFO关系private final long sequenceNumber;  /** The time the task is enabled to execute in nanoTime units */  private volatile long time;  private final Timer timer;  DelayedTimer(Timer timer, long nanos) {  this.timer = timer;  time = nanos;  sequenceNumber = sequencer.getAndIncrement();  }  final public long getDelay(TimeUnit unit) {  return  unit.convert(time - now(), TimeUnit.NANOSECONDS);  }  final void setTime(long nanos) {  time = nanos;  }  final Timer getTimer() {  return timer;  }  public int compareTo(Delayed other) {  if (other == this) { // compare zero ONLY if same object  return 0;  }  if (other instanceof DelayedTimer) {  DelayedTimer x = (DelayedTimer)other;  long diff = time - x.time;  //time<x.time 也就是说,other比较晚过期,排后面if (diff < 0) {  return -1;  } else if (diff > 0) {  **return 1;  } else if (sequenceNumber < x.sequenceNumber) {  //晚创建的任务,放到后面去return -1;  }  else {  return 1;  }  }        long d = (getDelay(TimeUnit.NANOSECONDS) -  other.getDelay(TimeUnit.NANOSECONDS));  return (d == 0) ? 0 : ((d < 0) ? -1 : 1);  }
}

参考后自己写一个

public class DelayObj implements Delayed {  private volatile long second;  public DelayObj(long second){  this.second = System.currentTimeMillis() + second*1000;  }  public void setTime(long nanos) {  second = nanos;  }  @Override  public long getDelay(TimeUnit unit) {  return second - System.currentTimeMillis();  }  @Override  public int compareTo(Delayed other) {  if (other == this) { // compare zero ONLY if same object  return 0;  }  if (other instanceof DelayObj) {  DelayObj x = (DelayObj)other;  long diff = second - x.second;  if (diff < 0) {  return -1;  } else if (diff > 0) {  return 1;  } else {  return 1;  }  }        long d = (getDelay(TimeUnit.NANOSECONDS) -  other.getDelay(TimeUnit.NANOSECONDS));  return (d == 0) ? 0 : ((d < 0) ? -1 : 1);  }  }

测试

public static void main(String[] args) throws InterruptedException {  DelayObj delayObj = new DelayObj(1);  DelayObj delayObj2 = new DelayObj(5);  DelayQueue<DelayObj> delayQueue = new DelayQueue<DelayObj>();  //五秒的先加,验证compareto是否符合逻辑delayQueue.add(delayObj2);  delayQueue.add(delayObj);  long l1 = System.currentTimeMillis();  DelayObj poll1 = delayQueue.take();  long l2 = System.currentTimeMillis();  System.out.println((l2-l1));  //998(1秒)DelayObj poll2 = delayQueue.take();  long l3 = System.currentTimeMillis();  System.out.println((l3-l1));  //4998(5秒)
}

DelayQueue 的简单使用相关推荐

  1. 【JAVA】延迟队列DelayQueue的应用

    最近在开发CRM管理系统时遇到一个需求:销售部门的人员在使用该系统时,可以从[线索公海]模块中 "领取" 潜在的客户线索到自己的[线索私海]模块中,成为自己私有的潜在客户线索,以便 ...

  2. 10分钟搞定 Java 并发队列

    前言 如果按照用途与特性进行粗略的划分,JUC 包中包含的工具大体可以分为 6 类: 执行者与线程池 并发队列 同步工具 并发集合 锁 原子变量 在[并发系列]中,主要讲解了 执行者与线程池,同步工具 ...

  3. 10分钟搞定 Java 并发队列好吗?好的

    前言 如果按照用途与特性进行粗略的划分,JUC 包中包含的工具大体可以分为 6 类: 执行者与线程池 并发队列 同步工具 并发集合 锁 原子变量 在[并发系列]中,主要讲解了 执行者与线程池,同步工具 ...

  4. Java高并发系列5-线程池

    Java高并发系列5-线程池 接上一篇Java并发系列4-并发容器我们继续 在编程中经常会使用线程来异步处理任务,但是每个线程的创建和销毁都需要一定的开销.如果每次执行一个任务都需要开个新线程去执行, ...

  5. 延迟消息解决方案总结(含源码)

    目录 前言 什么是延迟队列 可以实现的途径 关于上述几种方案的对比 解决方案 前言 先讲一下我们最近的两个业务场景: 稿件定时签发.用户可以指定每篇稿件的签发时间,达到时间点将稿件签发. 稿件发布超时 ...

  6. 每日一博 - DelayQueue阻塞队列源码解读

    文章目录 Pre DelayQueue特征 Leader/Followers模式 DelayQueue源码分析 类继承关系 核心方法 成员变量 构造函数 入队方法 offer(E e) 出队方法 po ...

  7. 原 荐 简单说说Kafka中的时间轮算法

    零.时间轮定义简单说说时间轮吧,它是一个高效的延时队列,或者说定时器.实际上现在网上对于时间轮算法的解释很多,定义也很全,这里引用一下 朱小厮博客 里出现的定义:参考下图,Kafka中的时间轮(Tim ...

  8. 阻塞队列之七:DelayQueue延时队列

    一.DelayQueue简介 是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走.这种队列是有序的(PriorityQueue实际 ...

  9. delayqueue_在DelayQueue中更改延迟,从而更改顺序

    delayqueue 因此,我正在考虑构建一个简单的对象缓存,该缓存在给定时间后会使对象过期. 显而易见的机制是使用Java并发包中的DelayedQueue类. 但是我想知道是否有可能在将对象添加到 ...

最新文章

  1. 一条直线上N个线段所覆盖的总长度
  2. Java学习总结:10
  3. 14岁初中生3天制成勒索病毒 制作方法或自学而成
  4. Spring Boot和Feign中使用Java 8时间日期API(LocalDate等)的序列化问题
  5. Spring Cloud Alibaba - 24 Gateway-路由、断言(Predicate)、过滤器(Filter)初体验
  6. 伽卡他卡电子教室 百度百科_怎么创建人物百度百科?人物百度百科创作技巧...
  7. Python 有序字典(OrderedDict)与 普通字典(dict)
  8. php用script判断闰年,php判断/计算闰年的方法小结【三种方法】
  9. 【Elasticsearch】使用索引生命周期管理实现热温冷架构
  10. SylixOS 内存管理源代码分析--phyPage.c
  11. 海康威视摄像头网线连接笔记本电脑,客户端提示:1连接设备失败。设备不在线或网络原因引起的连接超时等。(HCNetSDK.dll[7].)解决方案
  12. Git入门——tortoisegit使用问题:git不显示图标?
  13. Backdoor Attack with Imperceptible Input and Latent Modification
  14. 关于UE4中VR项目优化小记
  15. 如何在PHP中使用Modulo运算符
  16. sudo apt-get install package时出现E:无法定位软件包
  17. 将HTML文件转换为PDF文件(Thymeleaf模板转换,简单解决中文问题, 解决HTML带图片转换PDF文件问题)
  18. SpringBoot--访问静态页面
  19. uni-app watch computed API作用语法用法 +案例
  20. 生成服务器证书 启用HTTPS 生成自签名证书

热门文章

  1. android spc 能卸载吗,SPC中规格上限和下限怎么确定
  2. python houdini_【微笔记】houdini使用python创建城市教程笔记II
  3. 关于Unity中的资源管理,你可能遇到这些问题(UWA报告)
  4. cad绘图100实例解题_横沥CAD培训从入门到精通,CAD绘图技巧分享
  5. Mysql数据库给用户添加权限
  6. 数据结构课--并查集(标号法)
  7. 197. 上升的温度
  8. 软件体系结构复习资料
  9. Net::OICQ 还可以登录qq
  10. 【Android笔记50】Android应用如何获取系统服务(软键盘管理器、闹钟管理器)