SystemTimer,TimerTaskList等源码分析

一 SystemTimer

Kafka中定时器的实现,它在时间轮的基础上添加了执行到期任务,阻塞等待最近到期任务的功能

tickMs: Long 时间格

executorName: String 线程名字

wheelSize: Int 时间轮

startMs: Long 创建时间

taskExecutor:ExecutorService  固定线程池,由此线程执行定时到期任务

delayQueue:DelayQueue[TimerTaskList]  各个层级时间轮公用的DelayQueue,主要作用是阻塞推进时间轮指针的线程ExpiredOperationReaper,等待最近到期的任务

taskCounter:AtomicInteger 各个层级时间轮公用的任务个数计数器

timingWheel:TimingWheel 层级时间轮中对底层的时间轮

readWriteLock:ReentrantReadWriteLock 用来同步时间轮指针的currentTime修改后的读写锁

 

add 再添加过程中,如果发现任务已经到期,则将任务提交到taskExecutor执行;如果任务未到期,则调用TimerWheel.add提交到时间轮等待后期执行

def add(timerTask:TimerTask): Unit = {
  readLock.lock()
  try {
    // TimerTask封装成TimerTaskEntry,并计算到期时间
   
addTimerTaskEntry(newTimerTaskEntry(timerTask,timerTask.delayMs + SystemTime.hiResClockMs))
  } finally {
    readLock.unlock()
  }
}

 

addTimerTaskEntry 向时间轮提交添加任务

private def addTimerTaskEntry(timerTaskEntry: TimerTaskEntry): Unit = {
  // 向时间轮提交添加任务失败,任务可能到期或者取消
  if (!timingWheel.add(timerTaskEntry)) {
    // 如果不是取消,则提交给线程池
    if (!timerTaskEntry.cancelled)
      taskExecutor.submit(timerTaskEntry.timerTask)
  }
}

 

advanceClock 完成了时间轮指针的推进,同时对到期TimerTaskList的任务进行处理;如果TimerTaskList到期,但其中某些任务未到期 会将未到期的任务进行降级,添加到低层次的时间轮继续等待,如果任务到期了则提交到taskExecutor执行

def advanceClock(timeoutMs: Long): Boolean = {
  // 从队列取出第一个元素,如果不能立即取出,可以等待timeoutMs毫秒再取,还是没有取到返回空
  var bucket = delayQueue.poll(timeoutMs, TimeUnit.MILLISECONDS)
  if (bucket != null) {// 表示在队列阻塞期间有任务到期
    writeLock.lock()
    try {
      while (bucket != null) {
        // 尝试推进当前时间轮的指针,同时也会尝试推进上层时间轮的指针,随着当前时间轮的不断推进,上层时间轮指针早晚会被推进成功
        timingWheel.advanceClock(bucket.getExpiration())
        // 调用reinsert,尝试将bucket中的任务重新添加到时间轮,此过程可能会提交到taskExecutor线程执行,未到期的任务进行降级
        bucket.flush(reinsert)
        bucket = delayQueue.poll()// 非阻塞的取出第一个元素
      }
    } finally {
      writeLock.unlock()
    }
    true
  } else {
    false
  }
}

 

二 TimerTaskList源码分析

private[timer] class TimerTaskList(taskCounter: AtomicInteger) extends Delayed {

  // TimerTaskList 是一个双向的循环列表
  // root.next 指向下一个
  // root.prev 指向前一个
  // 创建一个TimerTaskEntry 节点,初始化next prev 都等于root,这是一个虚拟的TimerTaskEntry,并不存储任何任务
  private[this] val root = new TimerTaskEntry(null, -1)
  root.next = root
  root.prev = root
  // 初始化该环形双向链表到期时间
  private[this] val expiration = new AtomicLong(-1L)

  // 设置该环形双向链表的到期时间,如果里面的任务到期则交给线程执行,否则进行降级
  // 如果到期时间改变返回true
  def setExpiration(expirationMs: Long): Boolean = {
    expiration.getAndSet(expirationMs) != expirationMs
  }

  // 获取该环形双向链表的到期时间
  def getExpiration(): Long = {
    expiration.get()
  }

  // Apply the supplied function to each of tasks in this list
  def foreach(f: (TimerTask)=>Unit): Unit = {
    synchronized {
      // 获取下一个TimerTaskEntry节点
      var entry = root.next
      // 如果TimerTaskEntry不等于root
      while (entry ne root) {
        // 获取下一个TimerTaskEntry下一个节点
        val nextEntry = entry.next
        // 如果下一个entry没有被取消,调用函数f
        if (!entry.cancelled) f(entry.timerTask)
        entry = nextEntry
      }
    }
  }

  // Add a timer task entry to this list
  def add(timerTaskEntry: TimerTaskEntry): Unit = {
    var done = false
    while (!done) {
      // Remove the timer task entry if it is already in any other list
      // We do this outside of the sync block below to avoid deadlocking.
      // We may retry until timerTaskEntry.list becomes null.
      // 如果其他TimerTaskList也存在这个timerTaskEntry则删除它,避免死锁
      timerTaskEntry.remove()

      synchronized {
        timerTaskEntry.synchronized {
          // timerTaskEntry所在的TimerTaskList如果为空
          if (timerTaskEntry.list == null) {
            // put the timer task entry to the end of the list. (root.prev points to the tail entry)
            // 把当前timerTaskEntry放在队列尾部,并且前一个节点指向尾部的entry,下一个节点指向头部也
            val tail = root.prev
            timerTaskEntry.next = root
            timerTaskEntry.prev = tail
            timerTaskEntry.list = this
            tail.next = timerTaskEntry
            root.prev = timerTaskEntry
            taskCounter.incrementAndGet()// 时间轮任务总数+1
            done = true
          }
        }
      }
    }
  }

  // TimerTaskLKList删除指定的TimerTaskEntry
  def remove(timerTaskEntry: TimerTaskEntry): Unit = {
    synchronized {
      timerTaskEntry.synchronized {
        // 如果timerTaskEntry所在的TimerTaskList就是当前的TimerTaskList
        // 删除这个timerTaskEntry
        if (timerTaskEntry.list eq this) {
          timerTaskEntry.next.prev = timerTaskEntry.prev
          timerTaskEntry.prev.next = timerTaskEntry.next
          timerTaskEntry.next = null
          timerTaskEntry.prev = null
          timerTaskEntry.list = null
          taskCounter.decrementAndGet()// 时间轮任务总数-1
        }
      }
    }
  }

  // 删除所有的task entry,并且每一个task entry应用函数f
  def flush(f: (TimerTaskEntry)=>Unit): Unit = {
    synchronized {
      var head = root.next
      while (head ne root) {
        remove(head)
        f(head)
        head = root.next
      }
      expiration.set(-1L)
    }
  }

  def getDelay(unit: TimeUnit): Long = {
    unit.convert(max(getExpiration - SystemTime.hiResClockMs, 0), TimeUnit.MILLISECONDS)
  }

  def compareTo(d: Delayed): Int = {

    val other = d.asInstanceOf[TimerTaskList]

    if(getExpiration < other.getExpiration) -1
    else if(getExpiration > other.getExpiration) 1
    else 0
  }

}

 

三 TimerTaskEntry源码分析

private[timer] class TimerTaskEntry(val timerTask: TimerTask, val expirationMs: Long) extends Ordered[TimerTaskEntry] {

  @volatile
  var list: TimerTaskList = null // TimerTaskEntry所在的TimerTaskList双向循环链表
  var next: TimerTaskEntry = null // 下一个TimerTaskEntry
  var prev: TimerTaskEntry = null // 前一个TimerTaskEntry

  // 给当前TimerTaskEntry设置timer task
  if (timerTask != null) timerTask.setTimerTaskEntry(this)

  // 当前timer task entry是否取消了timer task
  def cancelled: Boolean = {
    timerTask.getTimerTaskEntry != this
  }

  def remove(): Unit = {
    var currentList = list
    // remove 被调用,其他的线程将会移动这个entry到一个其他的TimeTaskList,因此我们会重试直到TimeTaskList为空
    // 删除这个entry可能会失败,因为TimeTaskList的值的改变
    while (currentList != null) {
      // TimerTaskLKList删除指定的TimerTaskEntry
      currentList.remove(this)
      // TimerTaskLKList重新赋给currentList
      currentList = list
    }
  }

  override def compare(that: TimerTaskEntry): Int = {
    this.expirationMs compare that.expirationMs
  }
}

 

四 TimerTask分析

trait TimerTask extends Runnable {

  val delayMs: Long // timestamp in millisecond

  private[this] var timerTaskEntry: TimerTaskEntry = null

  def cancel(): Unit = {
    synchronized {
      if (timerTaskEntry != null) timerTaskEntry.remove()
      timerTaskEntry = null
    }
  }
  // 即某一个timer task entry希望持有这个timer task,但是其他的timer task正持有它,则就把当前的这个timer task entry给删掉
  private[timer] def setTimerTaskEntry(entry: TimerTaskEntry): Unit = {
    synchronized {
      // 如果某一个timer task被已经存在的timer task entry所持有,我们首先会删除这个timer task entry
      if (timerTaskEntry != null && timerTaskEntry != entry)
        timerTaskEntry.remove()

      timerTaskEntry = entry
    }
  }

  private[timer] def getTimerTaskEntry(): TimerTaskEntry = {
    timerTaskEntry
  }

}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫言静好、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值