Java定時任務以及ScheduledThreadPoolExecutor需要注意的問題

Java定時任務以及ScheduledThreadPoolExecutor需要注意的問題

   Java提供Timer和ScheduledThreadPoolExecutor兩個類實現定時任務,其中Timer簡單易用,但所有任務都是由同一個線程來調度,任務串行執行,任務之間存在互相干擾,一是前一個任務的延遲會導致後面的任務延遲,二是前一個任務異常導致後面的任務不再執行,三是Timer執行週期任務時依賴系統時間,如果當前系統時間發生變化,執行行爲也會出現變化。

 

   鑑於Timer的缺陷,Java 5提供了ScheduledThreadPoolExecutor實現定時任務,每個任務由線程池中一個線程去執行,任務併發執行,且相互之間不會受到干擾。此外,ScheduledExecutorService是基於時間延遲,不會由於系統時間的改變發生執行變化。但ScheduledThreadPoolExecutor要在某個時間點開始執行任務沒有Timer方便,需要先計算出和執行時間點的時間差,然後設置第一次啓動的延時。

 

   綜上,對於複雜的調度,最好是使用開源軟件,如Quartz。對於普通的週期性任務,使用ScheduledThreadPoolExecutor就可以滿足要求,但使用ScheduledThreadPoolExecutor時,必須注意兩點:

   1. 一定要使用try{}catch(Throwable t){}捕獲所有可能的異常,因爲ScheduledThreadPoolExecutor會在任務執行遇到異常時取消後續執行。

   2. 注意scheduleAtFixedRate與scheduleWithFixedDelay的區別,scheduleAtFixedRate是上一個任務開始執行之後延遲設定時間再執行,是從上一個任務開始時計時,但對於運行時長超過延遲時長的任務,會等上一個任務執行完之後,下一個任務纔開始執行,此時,延時沒有任何意義。而scheduleWithFixedDelay是在上一個任務結束執行之後延遲設定時間再執行,是從上一個任務結束時開始計算。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章