netty 的多路复用器的一个典型实现是NioEventLoop,而NioEventLoop的的reactor实现是一个非常高效的模式,可以支持在单线程情况下,完成如下工作,包括:
这里涉及到的定时任务执行离不开任务加入队列和出队列,而netty正是在AbstractScheduledEventExecutor类中聚合了自己的队列类,本文的主要目的便是介绍一下netty自己实现的这个任务队列,并就相关原理进行分析!
如下图所示是netty实现的优先级队列的继承关系
首先看看DefaultPriorityQueue的具体结构:
如上图可知优先级队列含有三个关键要素
优先级队列实现的堆的结构
通过DefaultPriorityQueue的实例化,我们找到了优先级队列的比较器具体实现,即通过ScheduledFutureTask的compareTo完成任务比较
!
ScheduledFutureTask进行优先级比较的本质,如下图所示,可以推断为当前任务的截止时间
,
当截止时间较长者则返回1,如果二者具有相同截止时间则由任务创建时候统一分配的任务id作为唯一标识!
因为这里的ScheduledFutureTask也是一个个人觉得很有设计感的地方,在此同样给出其相关图示!
堆中插入元素的关键就是插入元素与其父节点比较大小,满足条件则维持现状,不满足则进行交换!
下面以队列入队操作分析优先级队列的入队操作,如下所述是队列入队操作offer的基本逻辑,其重点方法为bubbleUp实现,其本质为堆结构的入堆操作!
这里是入堆操作的具体执行过程,从函数分析可知几个要点:
netty实现的优先级队列是一个小顶堆!
netty的出队过程就是堆的删除键堆顶元素的过程,这里包含两个步骤:
取最后一个元素自上而下进行堆化操作
;下图给出的为自上而下堆化过程的完整流程:
netty实现优先级队列的本质是利用堆,也就是数组的数据结构,实现队列接口的入队和出队操作接口
,具体任务是由自己编写的ScheduledFutureTask任务.这里有如下几点值得我们在以后的编程中借鉴和参考,再次总结如下:
截止时间长短作为优先级队列的比较凭据,实现一个定时任务执行器
----->每次取堆顶元素节点完成任务,代替了每次取整个任务列表执行任务!这样避免了频繁的扫描!
通过再次详细列出其流程主要目的是进一步复习一下堆这种数据结构!