DelayedOperaionPurgatory是一个相对独立的组件,它的主要功能是管理延迟操作。
TimingWheel
我们先来看一下它的核心字段:
bukets:其中的每一项都对应这一个时间格,同一个TimerTaskList中过的不同的定时任务的到期时间可能不同,但是相差在一个时间个的范围内
tickMs:当前时间轮中一个时间格表示的时间跨度
wheelSize:当前时间轮的格数,也是buckets数组的大小
taskCounter:各层级时间轮中任务的总数
startMs:当前时间轮的创建时间
queue:整个层级时间轮共用一个任务队列,其元素类型是TimerTaskList
currentTime:时间轮指针,将整个时间轮划分为到期部分和未到期部分
interval:当前时间轮的时间跨度
overflowWheel:上层时间轮的引用
在TimeWheel里面实现了时间轮的基础功能:
def add(timerTaskEntry: TimerTaskEntry): Boolean = {
val expiration = timerTaskEntry.expirationMs
if (timerTaskEntry.cancelled) {
//当前任务被取消
false
} else if (expiration < currentTime + tickMs) {
// 任务已到期
false
} else if (expiration < currentTime + interval) {
// 任务在当前时间跨度范围内,放到指定的桶里面
val virtualId = expiration / tickMs
val bucket = buckets((virtualId % wheelSize.toLong).toInt)
bucket.add(timerTaskEntry)
// 重新设置当前桶的到期时间
if (bucket.setExpiration(virtualId * tickMs)) {
//将当前桶添加到DelayQueue中
queue.offer(bucket)
}
true
} else {
// 任务的到期时间超过了当前时间轮的到期时间,将它交给上级时间轮来处理
if (overflowWheel == null) addOverflowWheel()
overflowWheel.add(timerTaskEntry)
}
}
private[this] def addOverflowWheel(): Unit = {
synchronized {
//如果上级时间轮为空,那么就创建一个
if (overflowWheel == null) {
overflowWheel = new TimingWheel(
tickMs = interval,
wheelSize = wheelSiz