DelayQueue 的简单使用
简介
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 的简单使用相关推荐
- 【JAVA】延迟队列DelayQueue的应用
最近在开发CRM管理系统时遇到一个需求:销售部门的人员在使用该系统时,可以从[线索公海]模块中 "领取" 潜在的客户线索到自己的[线索私海]模块中,成为自己私有的潜在客户线索,以便 ...
- 10分钟搞定 Java 并发队列
前言 如果按照用途与特性进行粗略的划分,JUC 包中包含的工具大体可以分为 6 类: 执行者与线程池 并发队列 同步工具 并发集合 锁 原子变量 在[并发系列]中,主要讲解了 执行者与线程池,同步工具 ...
- 10分钟搞定 Java 并发队列好吗?好的
前言 如果按照用途与特性进行粗略的划分,JUC 包中包含的工具大体可以分为 6 类: 执行者与线程池 并发队列 同步工具 并发集合 锁 原子变量 在[并发系列]中,主要讲解了 执行者与线程池,同步工具 ...
- Java高并发系列5-线程池
Java高并发系列5-线程池 接上一篇Java并发系列4-并发容器我们继续 在编程中经常会使用线程来异步处理任务,但是每个线程的创建和销毁都需要一定的开销.如果每次执行一个任务都需要开个新线程去执行, ...
- 延迟消息解决方案总结(含源码)
目录 前言 什么是延迟队列 可以实现的途径 关于上述几种方案的对比 解决方案 前言 先讲一下我们最近的两个业务场景: 稿件定时签发.用户可以指定每篇稿件的签发时间,达到时间点将稿件签发. 稿件发布超时 ...
- 每日一博 - DelayQueue阻塞队列源码解读
文章目录 Pre DelayQueue特征 Leader/Followers模式 DelayQueue源码分析 类继承关系 核心方法 成员变量 构造函数 入队方法 offer(E e) 出队方法 po ...
- 原 荐 简单说说Kafka中的时间轮算法
零.时间轮定义简单说说时间轮吧,它是一个高效的延时队列,或者说定时器.实际上现在网上对于时间轮算法的解释很多,定义也很全,这里引用一下 朱小厮博客 里出现的定义:参考下图,Kafka中的时间轮(Tim ...
- 阻塞队列之七:DelayQueue延时队列
一.DelayQueue简介 是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走.这种队列是有序的(PriorityQueue实际 ...
- delayqueue_在DelayQueue中更改延迟,从而更改顺序
delayqueue 因此,我正在考虑构建一个简单的对象缓存,该缓存在给定时间后会使对象过期. 显而易见的机制是使用Java并发包中的DelayedQueue类. 但是我想知道是否有可能在将对象添加到 ...
最新文章
- 一条直线上N个线段所覆盖的总长度
- Java学习总结:10
- 14岁初中生3天制成勒索病毒 制作方法或自学而成
- Spring Boot和Feign中使用Java 8时间日期API(LocalDate等)的序列化问题
- Spring Cloud Alibaba - 24 Gateway-路由、断言(Predicate)、过滤器(Filter)初体验
- 伽卡他卡电子教室 百度百科_怎么创建人物百度百科?人物百度百科创作技巧...
- Python 有序字典(OrderedDict)与 普通字典(dict)
- php用script判断闰年,php判断/计算闰年的方法小结【三种方法】
- 【Elasticsearch】使用索引生命周期管理实现热温冷架构
- SylixOS 内存管理源代码分析--phyPage.c
- 海康威视摄像头网线连接笔记本电脑,客户端提示:1连接设备失败。设备不在线或网络原因引起的连接超时等。(HCNetSDK.dll[7].)解决方案
- Git入门——tortoisegit使用问题:git不显示图标?
- Backdoor Attack with Imperceptible Input and Latent Modification
- 关于UE4中VR项目优化小记
- 如何在PHP中使用Modulo运算符
- sudo apt-get install package时出现E:无法定位软件包
- 将HTML文件转换为PDF文件(Thymeleaf模板转换,简单解决中文问题, 解决HTML带图片转换PDF文件问题)
- SpringBoot--访问静态页面
- uni-app watch computed API作用语法用法 +案例
- 生成服务器证书 启用HTTPS 生成自签名证书
热门文章
- android spc 能卸载吗,SPC中规格上限和下限怎么确定
- python houdini_【微笔记】houdini使用python创建城市教程笔记II
- 关于Unity中的资源管理,你可能遇到这些问题(UWA报告)
- cad绘图100实例解题_横沥CAD培训从入门到精通,CAD绘图技巧分享
- Mysql数据库给用户添加权限
- 数据结构课--并查集(标号法)
- 197. 上升的温度
- 软件体系结构复习资料
- Net::OICQ 还可以登录qq
- 【Android笔记50】Android应用如何获取系统服务(软键盘管理器、闹钟管理器)