2010-10-18 79 views
21

內聯Java IDE提示狀態「在循環中調用Thread.sleep可能導致性能問題。」我在文檔的其他地方找不到任何說明。這個說法。Thread.sleep()的Java性能問題

爲什麼?怎麼樣?還有什麼其他方法可以延遲執行線程?

+0

也許你可以改變這個問題來澄清它實際上是來自某個IDE的警告......比如「哪個性能問題可以用'調用...'來表示?」 – ShiDoiSi 2010-10-18 13:34:12

回答

6

這取決於等待是否依賴於另一個線程完成工作,在這種情況下,您應該使用在Java 1.6中引入的或high level concurrency classes。我最近不得不修復一些CircularByteBuffer代碼,它使用線程休眠而不是保護塊。使用先前的方法,無法確保正確的併發性。如果你只是希望線程能夠像遊戲一樣進入休眠狀態,那麼在覈心遊戲循環中暫停執行一定的時間,以便線程有很好的執行週期,Thread.sleep(..)非常好。

33

循環中不是Thread.sleep本身就是一個性能問題,但它通常暗示您做錯了什麼。

while(! goodToGoOnNow()) { 
    Thread.sleep(1000); 
} 

僅當您想暫停您的線程一段時間時才使用Thread.sleep。如果你想等待一定的條件,不要使用它。

對於這種情況,您應該使用wait/notify來替代或使用併發utils包中的某些構造。

只有在等待當前JVM外部的條件(例如等待另一個進程寫入文件)時才應使用Thread.sleep輪詢。

+0

感謝您的回覆。該線程通過TCP與外部設備進行通信,等待它開始運行: – fcw 2010-10-18 07:02:27

+0

該協議是,您正在運行?沒有睡覺.....你在跑步嗎?不,睡覺...你在跑嗎?是。繼續....所以沒有問題。謝謝! – fcw 2010-10-18 07:04:50

+0

不要忘記InterruptedException。 – 2015-08-11 19:34:42

5

這取決於你爲什麼要睡覺,以及你運行它的頻率。

我能想到的,可以適用於不同情況的幾個備選方案:

  • 讓線程芯片,後來開始一個新的(創建線程可能過於昂貴)
  • 使用的Thread.join()等待另一個線程死亡
  • 使用Thread.yield()來允許另一個線程來運行
  • 讓線程運行,但將其設置爲較低的優先級
  • Use wait() and notify()
0

我建議看看CountDownLatch類。網上有很多簡單的例子。當我剛剛開始多線程編程時,他們只是替換「睡眠while循環」的票據。

2

爲什麼?那是因爲上下文切換(部分OS CPU調度)

如何?調用Thread.sleep(t)使當前線程從正在運行的隊列移動到等待隊列。時間't'到達後,當前線程從等待隊列移動到就緒隊列,然後CPU需要一段時間才能選取並運行。

解決方法:調用Thread.sleep(t * 10);而不是調用10次循環內的Thread.Sleep(t)...

3

http://www.jsresources.org/faq_performance.html

1.6。 Thread.sleep()可以期望什麼精度?

短暫休眠的根本問題是睡眠呼叫完成當前調度時間片。只有在所有其他線程/進程完成後,該呼叫才能返回。

對於Sun JDK,在Windows上報告Thread.sleep(1)非常精確。對於Linux,它取決於內核的定時器中斷。如果內核編譯時HZ = 1000(默認爲alpha),則報告的精度很好。對於HZ = 100(x86上的默認值),它通常會休眠20 ms。

使用Thread.sleep(millis,nanos)不會改進結果。在Sun JDK中,納秒值只是四捨五入到最接近的毫秒。 (Matthias)

1

這可能不是問題,它取決於。

在我的情況下,我使用Thread.sleep()等待幾秒鐘,然後重新嘗試連接到外部進程。我有一個這個重新連接邏輯的while循環,直到達到最大嘗試次數。所以在我的情況下,Thread.sleep()純粹是爲了時間目的,而不是在多線程之間進行協調,這非常好。

您可以配置您的IDE如何處理此警告。