首页
学习
活动
专区
工具
TVP
发布

JDK源码那些事儿之DelayQueue

作为阻塞队列的一员,DelayQueue(延迟队列)由于其特殊含义而使用在特定的场景之中,主要在于Delay这个词上,那么其内部是如何实现的呢?今天一起通过DelayQueue的源码来看一看其是如何完成Delay操作的

前言

JDK版本号:1.8.0_171

DelayQueue内部通过优先级队列PriorityQueue来实现队列元素的排序操作,之前已经介绍过PriorityBlockingQueue的源码实现,两者比较类似,可自行回顾下,既然用到了优先级队列,则需要保证其队列元素的可比较性,以及延迟队列的特性(可计算延迟时间,通过延迟时间进行比较排序),故这里其中的队列元素需要实现Delayed接口,DelayQueue主要就在于理解这两部分内容

DelayQueue内部通过优先级队列PriorityQueue来实现队列元素的排序操作

DelayQueue队列元素需要实现Delayed接口(包含compareTo接口)

使用示例

下面示例代码部分已经显示了DelayQueue的用法,从名字命名上也能理解出其含义,延迟队列,主要在于延迟消费,如何实现呢?这里就需要用到Delayed接口,后面会进行说明,在使用时需要实现Delayed接口和compareTo接口

通过getDelay方法判断当前对象延迟时间是否已经到期

通过compareTo方法对其队列元素排序完成其队列元素出队的先后顺序

自己可以先试试运行结果,理解看看,可以看下调用poll和take的结果。如果用过rocketmq,可以类比其中的延迟消息队列,等到规定的时间再进行消费,只不过mq中的实现要比这复杂

类定义

Delayed

首先要说明的是Delayed接口,类定义部分也已经明确指出其使用(E extends Delayed),我们在操作时放入DelayQueue队列元素必须实现这个接口,实现其中的getDelay方法和compareTo方法,在使用示例代码部分我也说明了这两个方法的作用

常量/变量

其中使用了PriorityQueue来完成有序出队操作,与之前讲解过的PriorityBlockingQueue类似,有些许不同,可自行参考源码部分,也可以去看我之前的一篇专门讲解PriorityBlockingQueue源码的文章,主要异同在于PriorityQueue是非线程安全的,而PriorityBlockingQueue是线程安全的,内部排序机制使用的都是堆排序

如果你了解过PriorityQueue或PriorityBlockingQueue则在这里使用这个类是很容易理解源码实现人员的目的的,建议先去了解其实现,要不直接看这个源码比较有难度

由于需要实现延迟队列,使用PriorityQueue根据时间排序(自行实现具体细节,例如上边示例根据时间来排序),通过Delayed接口限制使用DelayQueue的场景

构造方法

构造方法比较简单,无参构造没有进行任何操作,有参构造方法直接传入对应类型的集合,循环add放入队列

重要方法

offer

入队操作,先获得lock,之后通过优先级队列的offer方法完成入队,同时判断是否要重置leader

poll

出队操作,先获得lock,之后通过优先级队列的poll方法完成出队,当然需要判断堆顶元素是否已到期。等待超时方法较为复杂,需耐心理解

take

出队操作,先获得lock,再通过判断最终执行poll完成出队操作,和poll的超时等待方法类似

drainTo

转移队列操作,内部是先通过peek方法先获取队列堆顶元素,判断其是否已到期,如到期则添加元素到新队列中,同时对原队列出队操作,当然,只转移已经到期的所有元素

其他方法如peek,size,clear,toArray,remove等都是通过优先级队列PriorityQueue来实现的,只是每次操作时需要先获得可重入锁保证线程安全

迭代器

迭代器的实现不是很复杂,迭代器复制了队列中的所有元素,需要注意的是,迭代器中的remove方法会通过removeEQ方法直接删除原PriorityQueue队列中的元素,不是删除拷贝的数据元素

总结

DelayQueue作为一个特殊的阻塞队列,主要在于Delay特性上,内部通过优先级阻塞队列和Delayed接口实现延迟的操作,如果之前已经了解了优先级队列,则非常容易理解其源码实现逻辑,复杂点的部分也就在于在多线程环境下入队一个新的更短的元素时内部做的处理,通过争抢leader来确定优先出队的那个线程,做不同的处理,比较有意思,可以参考文章多理解理解,不算过于复杂

以上内容如有问题欢迎指出,笔者验证后将及时修正,谢谢

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190928A0FMMN00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券