面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)

核心字段

  • prev、next。通过双向链表被用来在HashedWheelTimerBucket链timeouts(定时任务),由于只在WorkerThread上行动,没有必要进行同步/volatile。
  • 面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)
  • task,实际被调度的任务
  • 面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)
  • deadline,定时任务执行的时间。在创建 HashedWheelTimeout 时指定

计算公式:currentTime(创建 HashedWheelTimeout 的时间) + delay(任务延迟时间) - startTime(HashedWheelTimer 的启动时间),ns

面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)

state,定时任务当前所处状态

面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)

可选状态如下:

面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)

还有一个 STATE_UPDATER 字段用于实现 state 状态变更的原子性。

面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)

remainingRounds,当前任务剩余的时钟周期数。时间轮所能表示的时间长度有限,在任务到期时间与当前时刻的时间差,超过时间轮单圈能表示时长,就出现套圈,需要该字段值表示剩余的时钟周期。

面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)

核心API

  • isCancelled()
  • 面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)
  • isExpired()
  • 面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)
  • state()

检查当前 HashedWheelTimeout 状态

面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)

cancel() 方法

面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)

expire() 方法

面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)

remove()

面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)

HashedWheelBucket

时间轮中的一个槽。

时间轮中的槽实际上就是一个用于缓存和管理双向链表的容器,双向链表中的每一个节点就是一个 HashedWheelTimeout 对象,也就关联了一个 TimerTask 定时任务。


HashedWheelBucket 持有双向链表的首尾两个节点 - head 和 tail,再加上每个 HashedWheelTimeout 节点均持有前驱和后继引用,即可正、逆向遍历整个链表。

核心API

  • addTimeout()
  • 面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)
  • pollTimeout()
  • 面试Java后端却问我时间轮算法,面试官没想到我看过Dubbo源码!(中)
  • remove()
    从双向链表中移除指定的 HashedWheelTimeout 节点。
  • clearTimeouts()
    循环调用 pollTimeout() 方法处理整个双向链表,并返回所有未超时或者未被取消的任务。
  • expireTimeouts()

遍历双向链表中的全部 HashedWheelTimeout 节点。 在处理到期的定时任务时,会通过 remove() 方法取出,并调用其 expire() 方法执行;对于已取消的任务,通过 remove() 方法取出后直接丢弃;对于未到期的任务,会将 remainingRounds 字段(剩余时钟周期数)减一。


上一篇:我国自主研发手机操作系统 960 OS 发布


下一篇:用JS轻应用与HaaS 600实现语音播报音箱