2012-11-16 72 views
17

目標:每隔一段時間執行一次代碼。Thread.sleep()VS Executor.scheduleWithFixedDelay()

問題:在性能方面,有沒有之間的差異顯著:

while(true) { 
    execute(); 
    Thread.sleep(10 * 1000); 
} 

executor.scheduleWithFixedDelay(runnableWithoutSleep, 0, 10, TimeUnit.SECONDS); 

當然,後面的選項更加猶太教。然而,我想知道我是否應該開始一個名爲「花費幾天重構遺留代碼來告別Thread.sleep()」的冒險。

更新: 此代碼在超級/超級/超高負載環境中運行。

+0

採取我認爲兩者是相同的,'scheduleWithFixedDelay'封裝sleep調用。 –

+1

@喬伊:它們並不完全相同,因爲計劃的執行程序可以執行許多計劃任務,並以比任務數量少的線程運行它們。如果你只是使用睡眠,你必須爲每個「安排」任務設置一個線程。 –

+5

你爲什麼要問一個* sleep *操作的性能? – Dan

回答

6

你正在處理幾十秒鐘內的睡眠時間。通過改變您的睡眠選項可能節省的費用可能是納秒或微秒。

我每次都更喜歡後一種風格,但如果你有前者,而且要花很多錢去改變它,那麼「提高性能」並不是一個特別好的理由。

編輯重:8000個螺紋

8000線程是一個可怕的很多;我可能會轉移到預定的執行程序,以便您可以控制系統上的負載量。關於不同喚醒時間的觀點是值得注意的,儘管我認爲更大的風險是所有睡眠線程的大量涌入,然後緊密相繼喚醒並競爭所有系統資源。

我會花時間把這些全部扔進一個固定的線程池調度執行器。只有儘可能多的人可以同時運行,因爲你可以使用最有限的資源(例如#個內核或#IO路徑)以及幾個可以獲取任何污點的資源。這將以延遲爲代價爲您提供良好的吞吐量。

使用Thread.sleep()方法,將很難控制正在發生的事情,並且您可能會在吞吐量延遲上損失。

如果您需要更詳細的建議,您可能需要更詳細地描述您要做的事情。

+0

我的擔心是我們有8,000個線程,睡眠線程可能會得到如此低的優先級,以至於他們將執行很大的延遲,可能會產生GC的附帶問題。 – rudgirello

1

由於您還沒有提到Java版本,所以事情可能會改變。我回想起Java的源代碼,主要的區別在於內部編寫事物的方式。

對於的Sun Java 1.6如果使用第二種方法的本地代碼也帶來了在等待和通知呼叫系統。所以,以更高效的線程和CPU友好的方式。

但是,您又失去了控制權,並且您的代碼變得更加不可預測 - 考慮您想睡10秒。

所以,如果你想要更多的可預測性 - 當然你可以選擇1。

此外,在遺留系統中,當你遇到類似這樣的事情時 - 有80%的機會現在有更好的方法 - 但是這些幻數是有原因的(其餘20%)如此,風險自擔改變它:)

1

有不同的情況,

  1. 定時器產生持續更新的任務隊列。定時器完成後,可能不會立即收集垃圾。因此,創建更多定時器只會將更多對象添加到堆上。 Thread.sleep()只會暫停線程,所以內存開銷會非常低
  2. Timer/TimerTask也會考慮到您的任務的執行時間,所以它會更精確一些。它可以更好地處理多線程問題(如避免死鎖等)。
  3. 如果線程得到異常並被殺死,那就是一個問題。但是TimerTask會照顧它。它將運行,不管前一次運行失敗
  4. TimerTask的優點是它表達你的意圖好得多(即代碼可讀性),並且它已經實現了cancel()特性。

參考從here