时间轮

参考代码 hzlulu/TimingWheel

TimerTask

时间轮中任务类的抽象类。实现Runnable接口。
成员变量包括:

  • delayMs:超时的绝对时间
  • TimerTaskEntry:存放在时间轮中时,与之相关联的包装类,用于定时达到之前,取消任务。

TimerTaskEntry

时间格中存放的列表中的具体节点类,也是任务的包装类。实现了Comparable接口,根据每个Entry的expirationMs过期时间进行比较。
成员变量包括:

  • TimerTaskList:节点属于的时间格list
  • TimerTaskEntry next:指向下一个Entry
  • TimerTaskEntry pre:指向上一个Entry
  • TimerTask:包装的任务对象
  • expirationMs:到期时间

TimerTaskList

每个时间格表示的TimeTask列表,每个列表具有一个到期时间,当列表到期后,再将列表中的元素从新散布到时间格中。再散布的过程中会发现已经到期的任务,立即执行。
实现Delayed接口,提供getDelay方法返回给定单位的到期时间。
成员变量包括:

  • AtomicInteger taskCounter:列表中任务的个数
  • TimerTaskEntry root:列表的入口节点
  • AtomicLong expiration:列表的到期时间。这个时间根据tickMs粗化后的到期时间。例如,当tickMs为1ms时,到期时间就是任务的到期时间;当tickMs为2s时,两个相差1s的任务放在同一个时间格内时,设置list的到期时间是相同的。

TimingWheel

时间轮类。定义了整个时间轮的基本属性。
成员变量包括:

  • tickMs:时间格的单位
  • wheelSize:时间格的个数
  • interval:tickMs X wheelSize当前层时间轮的时间跨度
  • taskCounter:整个时间轮的任务数量
  • queue:时间格(TimerTaskList)按照到期时间组成的延时队列(在SystemTimer类的advanceClock中用来获取下一个时间格)
  • currentTime:时间轮的初始化时间
  • overflowWheel:高层时间轮
  • TimerTaskList[] buckets:时间格数组

SystemTimer

整个时间轮的包装和调用类。通过add方法向时间轮中添加任务。通过advanceClock方法驱动时间轮。

整个时间轮流程

初始化

SystemTimer systemTimer = new SystemTimer("name");

添加任务

  1. systemTimer.add(new DelayedOperation(100))
  2. 包装为TimerTaskEntry
  3. 向TimingWheel中添加
  4. 如果添加失败,则判断任务是否已经取消或者已经到期
  5. 如果任务到期则立即执行,taskExecutor.submit()

添加到时间轮的逻辑

  1. 判断任务是否已经取消
  2. 判断任务是否已经到期
  3. 如果到期时间在当前层时间轮的范围内,在计算对应的bucket天机
  4. 如果超出当前层的时间范围,则递归想高层时间轮继续添加

驱动时间轮

  1. systemTimer.advanceClock()
  2. 从当前层时间轮的延时队列中获取到期的TimeTaskList
  3. 修改时间轮的当前时间
  4. 将TimeTaskList中的任务继续添加到时间轮当中,此时会用到上一步修改的当前时间,来判断任务是否过期
  5. 对于过期任务直接执行,否则继续添加到时间轮中
  6. 继续从延时队列中获取到期的bucket,直到获取完。

你可能感兴趣的:(时间轮)