2009-01-03 49 views
221

我有我使用java.util.timer安排任務的代碼。我四處張望,看到ExecutorService可以做同樣的事情。所以這裏的這個問題,你有沒有使用Timer和ExecutorService來安排任務,使用另一個的好處是什麼?Java定時器與ExecutorService?

也想檢查是否有人使用Timer類,並遇到ExecutorService解決他們的任何問題。

+1

如果您還需要更多特色功能,請查看[quartz](http://www.quartz-scheduler.org/)。它爲您提供了更多的工作控制,包括計劃調度,集羣感知調度,對作業的個性化控制(一次運行一個概念,依賴關係等)。 --Tim – Tim 2009-01-04 16:36:40

回答

259

根據Java Concurrency in Practice

  • Timer可以是在系統時鐘變化敏感,ScheduledThreadPoolExecutor不是。
  • Timer只有一個執行線程,所以長時間運行的任務可以延遲其他任務。 ScheduledThreadPoolExecutor可以配置任意數量的線程。此外,如果需要,您可以完全控制創建的線程(通過提供ThreadFactory)。
  • 運行時異常拋出TimerTask殺死該線程,從而使Timer死:-(...即計劃的任務將不再運行ScheduledThreadExecutor不僅捕獲運行時異常,但它可以讓你處理它們,如果你想(通過重寫從ThreadPoolExecutorafterExecute法)。任務,其拋出的異常將被取消,但其他任務將繼續運行。

如果您可以使用ScheduledThreadExecutor代替Timer,這樣做。

一件事...而ScheduledThreadExecutor不適用於Java 1.4庫,有一個Backport of JSR 166 (java.util.concurrent) to Java 1.2, 1.3, 1.4,它有ScheduledThreadExecutor類。

20

ExecutorService更新更通用。計時器只是一個定期運行你計劃的東西的線程。

一個ExecutorService可能是一個線程池,甚至在集羣中全面鋪開其他系統和不喜歡的東西一次性批量執行等..

只要看看每個報價來決定。

56

如果它對您有用,那麼很難想出原因而不是使用Java 5執行器框架。電話:

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor(); 

會給你一個ScheduledExecutorService具有類似的功能Timer(即這將是單線程的),但其訪問可能稍微更具可擴展性(引擎蓋下,它採用並行結構,而不是完全同步與Timer類)。使用ScheduledExecutorService也給你,如優勢:

  • 您可以自定義它,如果需要的話(見newScheduledThreadPoolExecutor()ScheduledThreadPoolExecutor類)
  • 的「一次性」處決可以返回結果

關於堅持Timer的唯一原因我能想到的是:

  • 它可用於Java 5之前
  • 類似的類在J2ME中提供,它可以使移植的應用程序更容易(但它不會是非常困難的在這種情況下,增加一些抽象的公共層)
+0

使用`TimerTask`的另一個原因可能是`scheduledExecutionTime()`方法的可用性,它在`ScheduledExecutorService`中似乎沒有任何等價物。 – 2016-06-28 23:00:14

5

我的原因,有時寧願定時器通過Executors.newSingleThreadScheduledExecutor(),當我需要定時器在守護進程線程上執行時,我得到了更簡潔的代碼。

比較

private final ThreadFactory threadFactory = new ThreadFactory() { 
    public Thread newThread(Runnable r) { 
     Thread t = new Thread(r); 
     t.setDaemon(true); 
     return t; 
    } 
}; 
private final ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(threadFactory); 

private final Timer timer = new Timer(true); 

當我這樣做,我不需要一個ExecutorService的魯棒性。

2

從oralce的文檔頁面上ScheduledThreadPoolExecutor

的ThreadPoolExecutor它可另行安排命令在給定的延遲後運行,或定期地執行。當需要多個工作線程時,或者需要ThreadPoolExecutor(此類擴展)的附加靈活性或功能時,此類優於計時器

ExecutorService/ThreadPoolExecutorScheduledThreadPoolExecutor當你有多個工作線程時是很明顯的選擇。

優點的ExecutorService超過Timer

  1. Timer不能充分利用可用的CPU內核的不同ExecutorService尤其是使用的ExecutorService falvours多個任務,如ForkJoinPool
  2. ExecutorService如果你需要multple之間coordiantion提供colloborative API任務。假設你必須提交N個工作任務並等待完成所有這些任務。您可以通過invokeAll API輕鬆實現。如果您想通過多個Timer任務實現相同的目標,那麼這並不簡單。
  3. ThreadPoolExecutor爲線程生命週期的管理提供了更好的API。

    線程池解決兩個不同的問題:他們通常執行大量異步任務時,由於每個任務調用的開銷減少了提供更高的性能,以及它們提供邊界的手段和管理資源,包括線程,在執行任務集合時消耗。每一個的ThreadPoolExecutor還保持一些基本的統計數據,如完成任務

    很少有人數優勢:

    一個。您可以創建/管理/控制線程的生命週期&優化線程創建成本開銷

    b。您可以控制任務(偷工,ForkJoinPool,invokeAll)的處理等。

    c。您可以監視線程的進度和健康狀況

    d。提供更好的異常處理機制