SystemTimer,TimerTaskList等源码分析

来源:互联网 发布:java dbcp连接池配置 编辑:程序博客网 时间:2024/06/05 13:35

一 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提交到时间轮等待后期执行

defadd(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.MILLISECONDSif (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, -1root.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应用函数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 }}

 

三 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