2013-07-24 28 views
6

總是忽略InterruptedException的調用線程睡眠()當一個項目工作,我碰到這個代碼用於生產系統傳來:是以往任何時候都安全在Java

public static void sleepUntil(long millisecondToWake) { 
    while (true) { 
     long currentMillisecond = System.currentTimeMillis(); 
     if (currentMillisecond >= millisecondToWake) { 
      break; 
     } 
     try { 
      Thread.sleep(millisecondToWake - currentMillisecond); 
     } 
     catch (InterruptedException ignoredException) { 
      // do nothing 
     } 
    } 
} 

我一直堅持的基本在有效的Java暴露由Joshua布洛赫以及具有調試代碼我自己豐富的經驗,在那裏別人沒有下降的異常支持從來沒有下降的例外原則。到今天爲止,我還沒有發現它是一個好主意(有時能夠檢查異常,並拋出一個運行時debatably合理的,但我不是在這裏談論的情況下)的情況下。

先感謝您的任何意見。

+0

永遠是一個很好的選擇,留下一個空白抓。首先你不會注意到你的代碼出現故障。在產生這個異常時讀取,並編寫期望異常的代碼。 – logoff

+0

http://stackoverflow.com/q/824110/813951 –

回答

4

這裏是關於這個特定異常的大文章:

http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html

基本上但是,它不應該被忽視,最起碼的代碼應該做的是傳播中斷:

catch (InterruptedException e) { 
    // Restore the interrupted status 
    Thread.currentThread().interrupt(); 
} 

筆者不關心他的線程的睡眠被中斷(這是一個有效的理由吞下除外);然而,在作者不知道或想到的線程中,他可能需要中斷其他線程:

無論您是否打算對中斷請求執行操作,您仍然希望重新中斷當前線程,因爲單箇中斷請求可能有多個「收件人」。標準線程池(ThreadPoolExecutor)工作線程實現可響應中斷,因此中斷在線程池中運行的任務可能會取消任務並通知執行線程線程池正在關閉。

+0

奇怪的是,你的代碼示例不傳播異常。 –

+0

我認爲這個想法是,作者想讓線程進入睡眠狀態,而不必擔心處理異常。不同意或捍衛它。只是徵求更多有關它的教育意見。我確實閱讀過IBM的文章。它並沒有解決睡眠的問題。如果可能發生的更糟糕的事情是JVM在睡眠結束之前無法存在,那麼我懷疑這個代碼的作者會對它好,但我想知道是否會導致更糟糕的問題。謝謝! – codeotaku

+0

@JBNizet一點也不奇怪。我沒有提到傳播異常,我說傳播中斷。 – StuPointerException

3

這似乎並不在具體的例子合理的做法。特別是,如果用戶想退出程序(例如),JVM將掛起,直到你的睡眠方法結束,這似乎不合理。

海事組織,在這裏你可以放心地忽略一個InterruptedException的唯一情況是:

  • 你有線程執行你的方法完全控制,並
  • 異常被忽略立即退出後你。

在任何其他情況下,您應該:重置中斷標誌並立即退出。

例如,這將是確定:

//the task is local, nobody else can access it 
final Runnable localRunnable = new Runnable() { 
    public void run() { 
     //catch, ignore and exit immediately 
     try { Thread.sleep(10000); } catch (InterruptedException e) {} 
    } 
} 
//it is your own thread and you have full control over it 
new Thread(localRunnable).start(); 
+0

除了阻止即時JVM退出,還有其他可能的結果嗎? InterruptedException究竟是什麼信號?這也不清楚。謝謝。 – codeotaku

+0

@codeotaku中斷是Java中用於要求線程停止正在執行的操作的機制。例如,如果一個線程正在下載一個大文件並且你中斷了那個線程,你應該期望它停止下載,清理資源(關閉套接字等)並退出。當任務忽略中斷時,就無法阻止它。例如,關於第三方圖書館有許多關於忽視中斷並使其非常不友好的問題。在這種情況下唯一的解決方法是在自己的進程中運行代碼,這會使事情不必要地複雜化...... – assylias

相關問題