Java中常用的七个阻塞队列第二篇DelayQueue源码介绍
Java中常用的七个阻塞队列第二篇DelayQueue源码介绍
通过前面两篇文章,我们对队列有了了解及已经认识了常用阻塞队列中的三个了。本篇我们继续介绍剩下的几个队列。
本文主要内容:通过源码学习Delayqueue及理解Dqueue并用代码简单演示使用场景。
本文出自凯哥Java(kaigejava)的《凯哥Java并发系列》之《Java并发编程之队列》系列的第三篇:《Java中常用的七个阻塞队列第二篇DelayQueue源码介绍》
Java中常用的几个队列中,阻塞队列还有四个没介绍。如下图:
DelayQueue
先上总结脑图:
编辑
来看看构造器:
支持无参和支持直接存放一个集合的。
再来看看为什么说DQueue队列使用的是PriorityQueue实现的呢?
来看看源码:
在添加元素的offer方法源码中,我们可以看到最终调用的是q.offer(e)这个方法的。那么q又是什么呢?我们接着跟下去:private final PriorityQueue<E> q = new PriorityQueue<E>();。发现q是PriorityQueue这个队列。如下图:
为什么说可以延时呢?
我们来看看DQueyue类的定义:
public class DelayQueue<E extends Delayed> extends AbstractQueue<E>
implements BlockingQueue<E> {}
从源码中,我们可以看到DQueue队列中存放的元素必须要实现Delayed接口。
我们在来看看Delayed接口的方法:
只有,long getDelay(TimeUnit unit);方法。设置等待时间。
在从队列中获取数据的时候会对超时时间进行判断的。当超时时间小于等于0的时候,才会调用priorityQueue队列的poll()方法。具体源码如下:
从源码中,我们可以看到,DQueue延时处理的:
无界怎么理解?
说DQueue无界,我们应该从源码中查找。DQueue队列是基于PriorityQueue队列来实现的。那么我们就来看看PriorityQueue队列添加元素的源码。
从上图中,我们可以看到,在添加元素的时候offer方法会进行判断,当i的值大于等于队列的长的时候,会调用grow()方法来进行扩容。在grow方法中,我们可以看到会使用Arrsys.copyof()方法复制一份给队列。这样队列就完成了库容。没有大小的限制。所以说是无界的。
阻塞理解
当队列为空的时候,“获取/取”元素操作将会block,被阻塞着。我们来看看源码是怎么实现的。
从源码中我们可以看到,当从队列中获取元素的时候,先判断,如果第一个元素为空的时候,就等待。当等待的时间小于等于延时时间的话,就从队列中poll了;如果leader不为空的话,说明当前队列不是队首元素,依然await。
支持优先级
因为在PQueue队列的添加方法中,使用了comparator.compare方法。源码如下图:
所以通过源码分析我们可以到得到DelayQueue如下脑图:
使用场景:
DQueue非常有用的。我们利用DQueue的延时特性,可以讲DQueue应用于以下场景:
1:缓存的设计。可以利用Dqueue保存缓存元素的有效期。使用一个线程循环的从队列中获取数据。一旦获取到数据,就说明缓存有效期到了。
2:定时任务调度。可以使用Dqueue保存需要执行的任务和任务执行的时间,一旦从DQueue中获取到了任务,就开始执行任务了。比如TimerQueue就是使用了DelayQueue来实现的。
下面凯哥(凯哥Java:kaigejava)通过代码简单演示模拟缓存过期时间的案例。
代码演示:
需求:模拟缓存设置有效期。
说明:当从队列中获取到元素,说明元素的有效期到了。
模拟缓存的对象:
构造器:
需要注意:time=传递的time+当前时间。
实现了Delayed接口,需要重写getDelay和compartTo方法。
重写方法如下:
返回的是time与当前时间之间的差值。
compareTo方法如下:
调用方法:
来看看运行结果:
从运行结果中,我们可以看到,从打印出开始获取到k1的输出之间相差1s;K1与k2之间相差2s;K3和K2之间也相差2s.符合我们上面预设的时间差。
《Java并发系列教程》:

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Spring boot+redis实现消息发布与订阅
一.创建spring boot项目 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.41</version> </dependency&g...
-
下一篇
4月25日云栖号头条:支付宝、上汽集团、斑马网络联合打造“5G数字出行”
云栖号:https://yqh.aliyun.com第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策! 今日最新云头条快讯: 支付宝、上汽集团、斑马网络联合打造“5G数字出行” 4月24日,支付宝、上汽集团、斑马网络共同宣布将联合打造5G时代的“数字出行”样板,百万支付宝小程序率先“上车”,让车主通过语音、触控等交互方式就能获得覆盖行车前、中、后的一系列生活服务。即将发布的上汽荣威新款车型荣威RX5 PLUS会率先实现这一功能体验,首期上车的35款支付宝小程序,涵盖了交通出行、影音娱乐和休闲购物等方面。 上海虹口打造“5G+工业互联网”产业新高地 上海虹口区人民政府与上海市工业互联网协会23日签署战略合作协议。根据协议,双方将聚焦新技术、新业态、新经济,打造虹口新兴产业发展新亮点,构建具有区域特色优势的现代产业体系,积极推进该区在“5G+工业互联网”的产业研究、基础建设、创新应用场景建设和试点示范工作,打造虹口工业互联网品牌。 IPRdaily:2019年全球区块链专利申请量支付宝第一 权威知识产权机构IPRdaily今日发布全球区块链...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL数据库在高并发下的优化方案
- CentOS关闭SELinux安全模块
- SpringBoot2全家桶,快速入门学习开发网站教程
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- Docker快速安装Oracle11G,搭建oracle11g学习环境