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并发编程中涉 ...
随机推荐
- k8s集群移除node
先drain节点上的pod 使用kubectl drain node03 --delete-local-data --force --ignore-daemonsets 之后删除node [root@ ...
- SpringMVC笔记(五)
1. 拦截器 1.1 拦截器和过滤器 SpringMVC的处理器拦截器类似于Servlet开发过程中的过滤器Filter,用于对处理器进行预处理和后处理.我们可以自定义一些拦截器来实现特定的功能 过滤 ...
- 案例分析——Who is the king of handwriting notes?
案例分析--Who is the king of handwriting notes? 项目 内容 这个作业属于那个课程 2021春季学期软件工程(罗杰.任健) 这个作业的要求在哪里 案例分析 我在这 ...
- 微信小程序中的自定义组件
微信小程序中的组件 前言 之前做小程序开发的时候,对于开发来说比较头疼的莫过于自定义组件了,当时官方对这方面的文档也只是寥寥几句,一笔带过而已,所以写起来真的是非常非常痛苦!! 好在微信小程序的库从 ...
- hdu3074 线段树求区间乘积(单点更新)
题意: 给你n个数,两种操作,(1) 把第b个数改成c (2)算出b-c的乘积,结果对1000000007取余. 思路: 线段树单点更新,简单题目,不多解释,具体看代码. #i ...
- Day007 数组的声明与创建
数组 数组的定义 数组是相同类型数据的有序集合. 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成. 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们. 数组声 ...
- SpringBoot日志输出定义
在application.yml配置文件中添加 logging: level: root: INFO #根日志输出级别 com.juyss.dao: DEBUG #自定义包的日志输出级别 file: ...
- Mongodb安装配置以及在thinkphp中的使用
1.Mongodb安装 Mongodb安装参照此文档: https://www.runoob.com/mongodb/mongodb-window-install.html php的mongodb扩展 ...
- burp-suite(Web安全测试工具)教程
Burp Suite 是用于攻击web 应用程序的集成平台.它包含了许多工具,并为这些工具设计了许多接口,以促进加快攻击应用程序的过程.所有的工具都共享一个能处理并显示HTTP 消息,持久性,认证,代 ...
- sql常识-RIGHT JOIN
SQL RIGHT JOIN 关键字 RIGHT JOIN 关键字会右表 (table_name2) 那里返回所有的行,即使在左表 (table_name1) 中没有匹配的行. RIGHT JOIN ...