java DelayQueue延时队列的应用 原创 2022-07-07 13:39:07.0 阅读(1175)次 DelayQueue是一个线程安全的(ReentrantLock实现)、无界的(通过grow(int minCapacity)自动扩容,写不阻塞)、阻塞的(take方法会阻塞)、延迟(元素需要实现Delayed接口)队列,加入其中的元素必需实现Delayed接口。当调用put之类的方法加入元素时,会触发接口中的compareTo方法进行排序,也就是说队列中元素的顺序是按到期时间排序的(当然,compareTo方法需要我们自己去实现,如果实现不当,可能导致队头元素是没有过期的,而其他元素可能已经过期了),而非它们进入队列的顺序。排在队列头部的元素是最早到期的,越往后到期时间赿晚。没有过期元素的话,使用poll()方法会返回null值,超时判定是通过getDelay(TimeUnit.NANOSECONDS)方法的返回值小于等于0来判断。延时队列不能存放空元素。 那哪些场景会用到它呢,举个例子,定时重试的时候可以用它来做定时器,就不需要用到Timer或者quartz了,更加轻量级,下面给代码实例: ```java import com.mystudy.model.RetryTask; import java.util.concurrent.DelayQueue; /** * @ author: xxx * @ date: 2022/7/5 15:33 * @ description: 延时队列,到点出队 */ public class DelayQueueTest { public static void main(String args[]) throws InterruptedException { DelayQueue delayQueue = new DelayQueue(); new Thread(new Runnable() { @Override public void run() { delayQueue.offer(new RetryTask("task1",1000L,System.currentTimeMillis()+1000L)); delayQueue.offer(new RetryTask("task2",3900L,System.currentTimeMillis()+3900L)); delayQueue.offer(new RetryTask("task3",1900L,System.currentTimeMillis()+1900L)); delayQueue.offer(new RetryTask("task4",5900L,System.currentTimeMillis()+5900L)); delayQueue.offer(new RetryTask("task5",6900L,System.currentTimeMillis()+6900L)); delayQueue.offer(new RetryTask("task6",7900L,System.currentTimeMillis()+7900L)); delayQueue.offer(new RetryTask("task7",4900L,System.currentTimeMillis()+4900L)); } }).start(); while (true) { //挂起等着,有数据会赋值到task变量中 RetryTask task = delayQueue.take(); System.out.println(task); } } } ``` ```java import java.util.Date; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; /** * @ author: xxx * @ date: 2022/7/5 17:05 * @ description: */ @Data public class RetryTask implements Delayed { private String name; /** * 延时多少秒进行重试 */ private Long delaySeconds; /** * 重试的时间 */ private Long retryTime; public RetryTask(){} public RetryTask(String name,Long delaySeconds,Long retryTime){ this.name=name; this.delaySeconds=delaySeconds; this.retryTime=retryTime; } /** * 获取是否到期 * @param unit * @return */ @Override public long getDelay(TimeUnit unit) { return this.retryTime - System.currentTimeMillis(); } @Override public int compareTo(Delayed delayed) { RetryTask d2 = (RetryTask) delayed; long t = this.getDelay(TimeUnit.MILLISECONDS) -d2.getDelay(TimeUnit.MILLISECONDS); return Integer.valueOf(t+""); } @Override public String toString() { return "重试时间到点了,去重试吧,RetryTask{" + "name='" + name + '\'' + ", retryTime=" + (DateUtil.formatDateTime(new Date(retryTime))) + '}'; } } ``` 执行结果: ``` 重试时间到点了,去重试吧,RetryTask{name='task1', retryTime=2022-07-07 13:38:40} 重试时间到点了,去重试吧,RetryTask{name='task3', retryTime=2022-07-07 13:38:41} 重试时间到点了,去重试吧,RetryTask{name='task2', retryTime=2022-07-07 13:38:43} 重试时间到点了,去重试吧,RetryTask{name='task7', retryTime=2022-07-07 13:38:44} 重试时间到点了,去重试吧,RetryTask{name='task4', retryTime=2022-07-07 13:38:45} 重试时间到点了,去重试吧,RetryTask{name='task5', retryTime=2022-07-07 13:38:46} 重试时间到点了,去重试吧,RetryTask{name='task6', retryTime=2022-07-07 13:38:47} ``` java java基础 上一篇:获取eureka的注册服务的实例列表 下一篇:java.lang.NoClassDefFoundError: de/schlichtherle/license/LicenseManager
相关文章 java下载图片(976) java List间计算并集、差集、交集以及去重(3832) java程序员多线程常见的代码bug(1657) java使用BufferedImage放大或缩小图片(4643) java Md5工具类获取字符串的Md5值(1265) maven修改jar包版本不生效解决办法(7124) java stream List转Map与List转List与Map转List以及List转Map(8599) java父类转子类报错?怎么办?如何父类转子类(4508) 图片的base64字符转成BufferedImage(2665) java使用guava cache实现本地缓存(4854) 推荐文章 使用spring4实现websocket连接(1) Parameter index out of range (1 > number of parameters, which is 0(7) spring cloud+feign+mybatis中使用seata0.9实现分布式事务(7) spring cloud gateway报错Only one connection receive subscriber allowed(82) spring cloud中Feign调用诡异报错MethodNotAllowed: status 405 reading(116) elasticsearch7.1保存时报错: Validation Failed: 1: type is missing;(7) 聊聊数据保存到MySQL后数据乱码的问题(1) jquery对象与dom对象互转(1) linux使用epel源yum安装iftop、nload、nginx等(2) linux下nginx安装其他模块(1) 热门文章 java stream去重的几种方式(40819) the dependencies of some of the beans in the application context form a cycle(16324) 解决mybatis打印查询结果集造成太多日志的问题(9839) java enum枚举转list和Map(9722) java stream List转Map与List转List与Map转List以及List转Map(8468) ServletRequest转HttpServletRequest设置header之后取不到header的问题(8434) java中BufferedImage转成 base64字符串(8098) 切分List集合为多个List集合(7385) maven修改jar包版本不生效解决办法(6990) bootstrap.yml配置报错:Could not resolve placeholder 'xx' in value (6949) 标签列表 java java java java java java java基础 微服务 异常处理 mysql clickhouse clickhouse clickhouse clickhouse clickhouse spring cloud spring boot linux elasticsearch feign jdbc spring js docker postgresql solr seata nginx maven gateway hsqldb 数据库 架构 大数据分析 分布式事务 redis canal dubbo hadoop 消息队列 win10 websocket springmvc git html select2 mybatis jenkins rocketmq quartz activemq 数据库集群 ajax bat 电脑 笔记 eclipse 设计模式 阿里云 github freemarker jvm jquery javamail redission redission对象 hystrix http hibernate springmail svn ubuntu ueditor xheditor zookeeper 分布式 小程序 开发工具 gitlab