這是定時任務的線程池,用戶通過
schedule,scheduleAtFixedRate,scheduleWithFixedDelay
把定時任務加入到堆隊列中,工作線程取出隊列頭元素,當任務執行完成后,重新設置任務的執行時間,放回到隊列中。
使用過程中,有幾點需要注意:
1. scheduleAtFixedRate 和 scheduleWithFixedDelay 的任務執行時間不同
scheduleAtFixedRate 提交的任務,執行時間是 t, t+p, t+2p
scheduleWithFixedDelay 提交的任務,執行時間是前一次任務執行完成時間加上 period
2. 如果提交的定時任務執行過程中出現異常,並且沒有捕獲,導致異常被拋出,后續的定時任務不會再執行
3. 工作線程有 leader-follower 之分
假定工作線程沒有 leader-follower 區分,則 2 個線程嘗試獲取堆頂的任務,發現該任務並沒有到期,則掛起線程 t 時間,t 時間后,2 個線程被喚醒,再次嘗試獲取堆頂的任務,只有一個線程能獲取到任務,另一個線程獲取失敗由被掛起,這樣的掛起-喚醒-掛起,做了很多無用功。
采用 leader-follower 模式后,則 2 個線程嘗試獲取堆頂的任務,發現該任務並沒有到期,則搶占 leader,leader 掛起線程 t 時間,其他線程一直掛起,leader 線程取到堆頂元素后,重置 leader 為 null ,並喚醒其他掛起的線程。