java并发编程工具类JUC第三篇:DelayQueue延时队列

DelayQueue 是BlockingQueue接口的实现类,它根据"延时时间"来确定队列内的元素的处理优先级(即根据队列元素的“延时时间”进行排序)。另一层含义是只有那些超过“延时时间”的元素才能从队列里面被拿出来进行处理。
- DelayQueue 队列将阻止其元素对象从队列中被取出,直到达到为元素对象设置的延迟时间。DelayQueue 在队列的头部存储最近过期的元素,如果队列内没有元素过期,使用poll()方法获取队列内的元素将会返回null。
- DelayQueue 类及其迭代器实现了Collection和Iterator接口的所有可选方法,但迭代器方法
iterator()不能保证以特定的顺序遍历DelayQueue的元素。

- DelayQueue 不接收null元素,DelayQueue 只接受那些实现了java.util.concurrent.Delayed接口的对象,并将其放入队列内。DelayQueue 通过调用元素对象的getDelay(TimeUnit) 方法获取该元素剩余的“延迟时间”。getDelay()的 TimeUnit时间单位是一个枚举类型 : DAYS(天), HOURS(小时), MINUTES(分钟), SECONDS(秒), MILLISECONDS(毫秒), MICROSECONDS(微妙), NANOSECONDS(纳秒)
public interface Delayed extends Comparable{
long getDelay(TimeUnit unit);
}
下面我们就写一个java Class实现Delayed 接口,只有实现了Delayed 接口的类对象才能放入DelayQueue。因为Delayed接口继承自Comparable接口,所以我们必须实现getDelay方法和compareTo方法。
class DelayObject implements Delayed {
private String name;
private long time; //延时时间
public DelayObject(String name, long delayTime) {
this.name = name;
this.time = System.currentTimeMillis() + delayTime;
}
@Override
public long getDelay(TimeUnit unit) {
long diff = time - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed obj) {
if (this.time < ((DelayObject)obj).time) {
return -1;
}
if (this.time > ((DelayObject)obj).time) {
return 1;
}
return 0;
}
@Override
public String toString() {
Date date = new Date(time);
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return "\nDelayObject:{"
+ "name=" + name
+ ", time=" + sd.format(date)
+ "}";
}
}
测试延时队列DelayQueue的使用效果
public class DelayQueueTest {
@Test
void testDelayObject() throws InterruptedException {
//实例化一个DelayQueue
BlockingQueue<DelayObject> DQ = new DelayQueue<>();
//向DelayQueue添加四个元素对象,注意延时时间不同
DQ.add(new DelayObject("A", 1000 * 10)); //延时10秒
DQ.add(new DelayObject("B", 4000 * 10)); //延时40秒
DQ.add(new DelayObject("C", 3000 * 10)); //延时30秒
DQ.add(new DelayObject("D", 2000 * 10)); //延时20秒
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//将对象从DelayQueue取出,注意取出的顺序与延时时间有关
System.out.println( DQ.take()); //取出A
System.out.println( DQ.take()); //取出D
System.out.println( DQ.take()); //取出C
System.out.println( DQ.take()); //取出B
}
}
从下面的打印结果及上文的代码可以看出
- 队列中元素放入的顺序是A、B、C、D,取出的顺序是A、D、C、B,这是因为队列中的元素按照延时时间进行了排序。
- 另外我们可以看到,每隔10秒才可以从队列中取出一个元素,这是因为只有超过“延时时间”的元素才能从队列里面被拿出来。而我们设置的延时时间是10s、20s、30s、40s。
DelayObject:{name=A, time=2021-03-23 14:14:20}
DelayObject:{name=D, time=2021-03-23 14:14:30}
DelayObject:{name=C, time=2021-03-23 14:14:40}
DelayObject:{name=B, time=2021-03-23 14:14:50}
欢迎关注我的博客,里面有很多精品合集
- 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。
- 《手摸手教你学Spring Boot2.0》
- 《Spring Security-JWT-OAuth2一本通》
- 《实战前后端分离RBAC权限管理系统》
- 《实战SpringCloud微服务从青铜到王者》
- 《VUE深入浅出系列》
java并发编程工具类JUC第三篇:DelayQueue延时队列的更多相关文章
- java并发编程工具类JUC第四篇:LinkedBlockingQueue链表队列
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue. LinkedBlockingQueue 队列是Blo ...
- java并发编程工具类JUC第七篇:BlockingDeque双端阻塞队列
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...
- java并发编程工具类JUC第八篇:ConcurrentHashMap
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...
- java并发编程工具类JUC第一篇:BlockingQueue阻塞队列
Java BlockingQueue接口java.util.concurrent.BlockingQueue表示一个可以存取元素,并且线程安全的队列.换句话说,当多线程同时从 JavaBlocking ...
- java并发编程工具类JUC第二篇:ArrayBlockingQueue
类ArrayBlockingQueue是BlockingQueue接口的实现类,它是有界的阻塞队列,内部使用数组存储队列元素.这里的"有界"是指存储容量存在上限,不能无限存储元素. ...
- Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo
Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo CountDownLatch countDownLatch这个类使一个线程等待其他线程 ...
- java并发编程工具类辅助类:CountDownLatch、CyclicBarrier和 Semaphore
在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 以下 ...
- 【java并发编程艺术学习】(三)第二章 java并发机制的底层实现原理 学习记录(一) volatile
章节介绍 这一章节主要学习java并发机制的底层实现原理.主要学习volatile.synchronized和原子操作的实现原理.Java中的大部分容器和框架都依赖于此. Java代码 ==经过编译= ...
- Java并发编程入门,看这一篇就够了
Java并发编程一直是Java程序员必须懂但又是很难懂的技术内容.这里不仅仅是指使用简单的多线程编程,或者使用juc的某个类.当然这些都是并发编程的基本知识,除了使用这些工具以外,Java并发编程中涉 ...
随机推荐
- 一次死锁导致CPU异常飘高的整个故障排查过程
目录 一.问题详情 top 命令截图 联系腾讯云排查 检查系统日志发现异常 二. 问题解析 三.问题原因 最终结论 四.扩展 进程的几种状态 马后炮 如何快速清理僵尸进程(Z) 内核参数相关 如何查看 ...
- JavaScript设计模式(二):工厂模式
工厂模式模式的定义与特点 工厂模式(Factory Pattern)是编程中最常用的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式.在工厂模式中,我们在创建对象时不会对 ...
- 1026 Table Tennis
A table tennis club has N tables available to the public. The tables are numbered from 1 to N. For a ...
- YII框架的自定义布局(嵌套式布局,版本是1.1.20)
0x01 创建控制器 0x02 创建文件夹,之后创建视图文件 0x03 浏览器访问cxy/index控制器,验证 以上就是使用默认的布局,非常简单,那么如果我不想用YII框架默认的布局呢,我想用自定义 ...
- 仁者见仁:缓冲区栈溢出之利用 Exploit 形成完整攻击链完全攻略(含有 PayLoad)
> 前言 内存缓冲区溢出又名 Buffer OverFlow,是一种非常危险的漏洞,在各种操作系统和应用软件中广泛存在.利用缓冲区溢出进行的攻击,小则导致程序运行失败.系统宕机等后果,大则可以取 ...
- Win64 驱动内核编程-10.突破WIN7的PatchGuard
突破WIN7的PatchGuard WIN64 有两个内核保护机制,KPP 和 DSE.KPP 阻止我们 PATCH 内核,DSE 拦截我们加载驱动.当然 KPP 和 DSE 并不是不可战胜的,WIN ...
- 【.Net Core】分析.net core在linux下内存占用过高问题
现象 随着程序运行,内存占用率越来越高,直到触发linux的OOM,程序被杀死. 分析工具 运行环境:.net core 3.1(微软的分析工具要求最低3.0,无法分析2.1的core程序,需要先改为 ...
- LeetCode 26. 删除有序数组中的重复项
双指针法 分析: 设置两个指针:p1,p2,初始p1指向数组的第一个元素,p2指向第二个元素 1)如果p1的值 == p2的值,就让p2后移一位 2)如果p1的值 != p2的值,修改p1的下一个元素 ...
- 这次我好像才真的明白了CSS Rem字体计算的原理
背景 如何按照设计稿中标注的尺寸,直接写页面的样式,不再需要px2rem这样的工具或者人工转换 ? 只要你明白了rem的计算原理,这个问题的答案超级简单. 根字体大小计算核心原理 设备的根字体大小 * ...
- Linux 中如何使用 IP 命令
老版本的 Linux 中都是使用 ifconfig 命令检查和配置网络接口,但是该命令目前已经没有维护了,取而代之的是 ip 命令 ip 命令和 ifconfig 命令很相似,但是 相比起来,ip命令 ...