天天看點

面試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 節點均持有前驅和後繼引用,即可正、逆向周遊整個連結清單。

  • addTimeout()
  • 面試Java後端卻問我時間輪算法,面試官沒想到我看過Dubbo源碼!(中)
  • pollTimeout()
  • 面試Java後端卻問我時間輪算法,面試官沒想到我看過Dubbo源碼!(中)
  • 從雙向連結清單中移除指定的 HashedWheelTimeout 節點。
  • clearTimeouts()

    循環調用 pollTimeout() 方法處理整個雙向連結清單,并傳回所有未逾時或者未被取消的任務。

  • expireTimeouts()

周遊雙向連結清單中的全部 HashedWheelTimeout 節點。 在處理到期的定時任務時,會通過 remove() 方法取出,并調用其 expire() 方法執行;對于已取消的任務,通過 remove() 方法取出後直接丢棄;對于未到期的任務,會将 remainingRounds 字段(剩餘時鐘周期數)減一。