爲什麼調用catch塊中的方法Thread.currentThread.interrupt()?爲什麼在一個捕獲InterruptException塊中調用Thread.currentThread.interrupt()?
回答
這樣做是爲了保持狀態。
當你趕上InterruptException
把它吞了,你基本上是防止任何更高級別的方法/線程組注意不到中斷。這可能會導致問題。
通過調用Thread.currentThread().interrupt()
,您設置線程的中斷標誌,所以更高級別中斷處理程序會注意到這一點,並能妥善處理這個問題。
Java Concurrency in Practice在中對此進行了更詳細的討論第7.1.3章:響應中斷。它的規則是:
只有實現線程中斷策略的代碼才能吞下中斷請求。通用任務和庫代碼不應該吞服中斷請求。
我會認爲這是一個不好的做法,或至少有點冒險。 通常更高級別的方法不會執行阻止操作,並且它們在此處永遠不會看到InterruptedException
。如果你在每個執行可中斷操作的地方都將其掩蓋起來,你永遠不會得到它。
爲Thread.currentThread.interrupt()
和不加任何其它異常或以任何其他方式信號的中斷請求(例如,設置在一個線程中的主循環interrupted
局部變量變量)的唯一理由是,你真的不能用異常做任何事情的情況,就像在finally
塊中一樣。
遇見了彼得Török的答案,如果你想更好地瞭解Thread.currentThread.interrupt()
呼叫的影響。
注:
如何停止等待很長時間線程(例如,用於輸入)?
對於這種技術的工作,它的關鍵,映入中斷異常,是不是準備好應對任何方法立即重新例外。我們說reasserts而不是rethrows,因爲它不總是可能重新拋出異常。 如果捕獲InterruptedException的方法沒有聲明拋出這個(選中)異常,那麼就應該「reinterrupt本身」具有以下咒語:
Thread.currentThread().interrupt();
這確保了主題將盡快重新調用InterruptedException。
我覺得這個代碼示例使事情變得有點清晰。 其中從事這項工作的類:
public class InterruptedSleepingThread extends Thread {
@Override
public void run() {
doAPseudoHeavyWeightJob();
}
private void doAPseudoHeavyWeightJob() {
for (int i=0;i<Integer.MAX_VALUE;i++) {
//You are kidding me
System.out.println(i + " " + i*2);
//Let me sleep <evil grin>
if(Thread.currentThread().isInterrupted()) {
System.out.println("Thread interrupted\n Exiting...");
break;
}else {
sleepBabySleep();
}
}
}
/**
*
*/
protected void sleepBabySleep() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
主類:
public class InterruptedSleepingThreadMain {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
InterruptedSleepingThread thread = new InterruptedSleepingThread();
thread.start();
//Giving 10 seconds to finish the job.
Thread.sleep(10000);
//Let me interrupt
thread.interrupt();
}
}
嘗試調用中斷,而不設置狀態回來了。
真棒例子,謝謝。 – Ben 2015-04-09 19:29:56
- 1. 爲什麼要捕獲InterruptedException來調用Thread.currentThread.interrupt()?
- 2. 爲什麼在捕獲異常時調用Timer回調停止?
- 3. 爲什麼不能在一個Python中調用可調用的塊?
- 4. 存在System.ArgumentException異常的捕獲塊,但是異常無法捕獲,爲什麼?
- 5. Java:爲什麼在第二個方法catch塊中沒有捕獲異常
- 6. 爲什麼重新拋出捕獲的異常在finally塊
- 7. 什麼是塊變量捕獲?
- 8. 獲取一個未捕獲的typerror,不知道爲什麼
- 9. 捕獲塊行爲
- 10. 爲什麼會捕獲所有的塊實際上並沒有捕獲所有
- 11. 爲什麼這個AJAX調用不能捕獲Symfony中的onChange事件?
- 12. 爲什麼我不在控制器中捕獲這個JSON?
- 13. 爲什麼_CxxUnhandledExceptionFilter被調用而不是被catch(...)捕獲(...)
- 14. 爲什麼在另一個線程中調用Console.WriteLine的Console.ReadKey()塊輸出?
- 15. 爲什麼不用NSNotificationCenter調用該塊?
- 16. 在Java 7 multicatch塊中捕獲異常的類型是什麼?
- 17. 爲什麼使用strace只能捕獲一次系統調用(getpid)?
- 18. 爲什麼通過捕獲操作符在Elixir 1.4.2中調用代理#更新?
- 19. 爲什麼SystemC跟蹤無法捕獲上一個波形?
- 20. 爲什麼我必須在調用構造函數時將lambda捕獲到一個字段變量中
- 21. 爲什麼正確調用完成塊?
- 22. 爲什麼從python塊調用ffmpeg?
- 23. 爲什麼立即調用完成塊?
- 24. 如何捕獲一個代碼塊調用的函數中使用C#
- 25. 爲什麼在foreach循環中嘗試捕獲是一個好習慣?
- 26. 爲什麼你不能在Java中拋出並捕獲一個對象?
- 27. 爲什麼不在GWT中右擊捕獲在IE中工作?
- 28. 你爲什麼要從一個塊創建一個模塊?
- 29. 爲什麼捕獲說明符在捕獲列表中是可選的?
- 30. 在這個C++代碼中捕獲的用法是什麼
在[documentation](https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html)中聲明_「按照慣例,任何通過拋出一個`InterruptedException`退出的方法**清除中斷狀態**當它這樣做。我認爲這使得答案更清晰_why_你需要保持中斷狀態。 – 2016-02-04 13:52:22