DelayQueue怎么用
原文 https://www.toocruel.net/delayqueue/
DelayQueue简介
DelayQueue 是一个无界阻塞队列,要添加进去的元素必须实现Delayed接口,只有在延迟期满时才能从中提取元素。
该队列的头部 是延迟期满后保存时间最长的 Delayed 元素。
如果延迟都还没有期满,则队列没有头部,并且 poll 将返回 null。
当一个元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于等于 0 的值时,表示该元素到期了。
无法使用 take 或 poll 移除未到期的元素,也不会将这些元素作为正常元素对待。例如,size 方法同时返回到期和未到期元素的计数。
此队列不允许使用 null 元素。
怎么用
首先,定义元素类
DelayQueue只能添加(offer/put/add)实现了Delayed接口的对象,意思是说我们不能想往DelayQueue里添加什么就添加什么,不能添加int、也不能添加String进去,必须添加我们自己的实现了Delayed接口的类的对象,来代码:
/*** compareTo 方法必须提供与 getDelay 方法一致的排序*/
class MyDelayedTask implements Delayed{private String name ;private long start = System.currentTimeMillis();private long time ;public MyDelayedTask(String name,long time) {this.name = name;this.time = time;}/*** 需要实现的接口,获得延迟时间 用过期时间-当前时间* @param unit* @return*/@Overridepublic long getDelay(TimeUnit unit) {return unit.convert((start+time) - System.currentTimeMillis(),TimeUnit.MILLISECONDS);}/*** 用于延迟队列内部比较排序 当前时间的延迟时间 - 比较对象的延迟时间* @param o* @return*/@Overridepublic int compareTo(Delayed o) {MyDelayedTask o1 = (MyDelayedTask) o;return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));}@Overridepublic String toString() {return "MyDelayedTask{" +"name='" + name + '\'' +", time=" + time +'}';}
}
其中,compareTo 方法 getDelay 方法 就是Delayed接口的方法,我们必须实现,而且按照JAVASE文档,compareTo 方法必须提供与 getDelay 方法一致的排序,也就是说compareTo方法里可以按照getDelay方法的返回值大小排序,即在compareTo方法里比较getDelay方法返回值大小
写main方法测试
定义一个DelayQueue,添加几个元素,while循环获取元素
private static DelayQueue delayQueue = new DelayQueue();public static void main(String[] args) throws InterruptedException {new Thread(new Runnable() {@Overridepublic void run() {delayQueue.offer(new MyDelayedTask("task1",10000));delayQueue.offer(new MyDelayedTask("task2",3900));delayQueue.offer(new MyDelayedTask("task3",1900));delayQueue.offer(new MyDelayedTask("task4",5900));delayQueue.offer(new MyDelayedTask("task5",6900));delayQueue.offer(new MyDelayedTask("task6",7900));delayQueue.offer(new MyDelayedTask("task7",4900));}}).start();while (true) {Delayed take = delayQueue.take();System.out.println(take);}}
执行结果
符合预期
MyDelayedTask{name='task3', time=1900}
MyDelayedTask{name='task2', time=3900}
MyDelayedTask{name='task7', time=4900}
MyDelayedTask{name='task4', time=5900}
MyDelayedTask{name='task5', time=6900}
MyDelayedTask{name='task6', time=7900}
MyDelayedTask{name='task1', time=10000}
附完整代码
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;/*** @Description* @Auther sty* @createTime 2018/9/18 下午2:52*/
public class DelayQueueTest {private static DelayQueue delayQueue = new DelayQueue();public static void main(String[] args) throws InterruptedException {new Thread(new Runnable() {@Overridepublic void run() {delayQueue.offer(new MyDelayedTask("task1",10000));delayQueue.offer(new MyDelayedTask("task2",3900));delayQueue.offer(new MyDelayedTask("task3",1900));delayQueue.offer(new MyDelayedTask("task4",5900));delayQueue.offer(new MyDelayedTask("task5",6900));delayQueue.offer(new MyDelayedTask("task6",7900));delayQueue.offer(new MyDelayedTask("task7",4900));}}).start();while (true) {Delayed take = delayQueue.take();System.out.println(take);}}
}/*** compareTo 方法必须提供与 getDelay 方法一致的排序*/
class MyDelayedTask implements Delayed{private String name ;private long start = System.currentTimeMillis();private long time ;public MyDelayedTask(String name,long time) {this.name = name;this.time = time;}/*** 需要实现的接口,获得延迟时间 用过期时间-当前时间* @param unit* @return*/@Overridepublic long getDelay(TimeUnit unit) {return unit.convert((start+time) - System.currentTimeMillis(),TimeUnit.MILLISECONDS);}/*** 用于延迟队列内部比较排序 当前时间的延迟时间 - 比较对象的延迟时间* @param o* @return*/@Overridepublic int compareTo(Delayed o) {MyDelayedTask o1 = (MyDelayedTask) o;return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));}@Overridepublic String toString() {return "MyDelayedTask{" +"name='" + name + '\'' +", time=" + time +'}';}
}
DelayQueue怎么用相关推荐
- 【Java并发编程】20、DelayQueue实现订单的定时取消
当订单定时取消需要修改数据库订单状态,但是怎么确定订单什么时候应该改变状态,解决方案有下面两种: 第一种,写个定时器去每分钟扫描数据库,这样更新及时,但是如果数据库数据量大的话,会对数据库造成很大的 ...
- java加载c库阻塞_【死磕Java並發】-----J.U.C之阻塞隊列:DelayQueue
DelayQueue是一個支持延時獲取元素的無界阻塞隊列.里面的元素全部都是"可延期"的元素,列頭的元素是最先"到期"的元素,如果隊列里面沒有元素到期,是不能從 ...
- 每日一博 - DelayQueue阻塞队列源码解读
文章目录 Pre DelayQueue特征 Leader/Followers模式 DelayQueue源码分析 类继承关系 核心方法 成员变量 构造函数 入队方法 offer(E e) 出队方法 po ...
- Java DelayQueue延迟队列的使用和源码分析
文章目录 概述 示例 原理分析 概述 DelayQueue 是JAVA提供的延时队列,队列内部的对象必须实现 Delayed 接口,该接口只有一个 getDelay 方法,返回延迟执行的时长. pub ...
- 使用DelayQueue 和 FutureTask 实现java中的缓存
使用DelayQueue.ConcurrentHashMap.FutureTask实现的缓存工具类. DelayQueue 简介 DelayQueue是一个支持延时获取元素的无界阻塞队列.DelayQ ...
- DelayQueue源码
介绍 一个实现PriorityBlockingQueue实现延迟获取的无界队列,在创建元素时,可以指定多久才能从队列中获取当前元素.只有延时期满后才能从队列中获取元素.(DelayQueue可以运用在 ...
- DelayQueue详解
一.DelayQueue是什么 DelayQueue是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走.这种队列是有序的,即队头对 ...
- java中DelayQueue的使用
文章目录 简介 DelayQueue DelayQueue的应用 总结 java中DelayQueue的使用 简介 今天给大家介绍一下DelayQueue,DelayQueue是BlockingQue ...
- 阻塞队列之七:DelayQueue延时队列
一.DelayQueue简介 是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走.这种队列是有序的(PriorityQueue实际 ...
- delayqueue_在DelayQueue中更改延迟,从而更改顺序
delayqueue 因此,我正在考虑构建一个简单的对象缓存,该缓存在给定时间后会使对象过期. 显而易见的机制是使用Java并发包中的DelayedQueue类. 但是我想知道是否有可能在将对象添加到 ...
最新文章
- 自制的一个eclipse 插件jcodesmith(代码生成器)
- 解决ubuntu ufw开启时,kvm虚拟机网络全部无法访问
- python event多线程回调
- LVQ模型Python实现
- 《每日一题》49. Group Anagrams 字母异位词分组
- react全局状态管理_react 状态管理的复杂度来源
- 一段js面向对象的写法
- oracle server process,Oracle体系结构及备份(四)server-process
- lecture 16:DID双重差分方法
- DSL是什么意思?Mbps是什么意思?
- mtk android 关机充电,MTK充电开机关机过程
- 01 Spark组件 —— Scala导言
- 华为路由器用Linux开发,华为路由器常用配置 - osc_1v2pb1nt的个人空间 - OSCHINA - 中文开源技术交流社区...
- [SCOI2012]喵星球上的点名[广义后缀自动机]
- 牛掰!我是这么把博客粉丝转到公众号的
- python中的Queue
- 千万不要说联通的网络不好……
- Eclipse的常用快捷键
- 郑林楷计算机系姚班,郑林楷为什么被清华录取 郑林楷在清华很厉害吗
- 行为识别 人体骨架检测+LSTM