一些解釋第一:
線程的中斷狀態基本上是一個布爾標誌,它被設置爲「真」的interrupt()
。 該標誌的當前狀態可以是閱讀使用Thread.currentThread().isInterrupted()
。
如果中斷操作(如Object.wait()
或Thread.sleep()
)發現中斷標誌設置 會拋出InterruptedException
,並在同一時間明確(設置爲「假」)的標誌,它看起來是這樣的:
if (Thread.interrupted()) { throw new InterruptedException(); }
請注意並記住Thread.interrupted()
隱式清除中斷標誌! 這意味着,在您執行catch(InterruptedException ie) {...}
時,線程本身並不知道它已被中斷。
那麼,讓我們來看看兩個例子:
首先它支持取消任務的一個例子。 在這裏,我們並不真正關心多遠被中止前的任務來進行:
public void run() {
int x = 0;
try {
while (x < 10) {
Thread.sleep(1000); // Some interruptible operation
x++;
}
System.out.println("x = " + x);
} catch (InterruptedException ie) {
System.out.println("Interrupted: x = " + x);
// We know we've been interrupted.
// Let the caller know it, too:
Thread.currentThread().interrupt();
}
}
此代碼試圖如果它不被中斷數從0 x到10,這將完成輸出「X = 10" 。 但是,如果線程在兩者之間中斷,則將拋出InterruptedException
,從而中止正在執行的增加x的任務。 在這種情況下,根據線程何時中斷,輸出可能是「中斷:x = 0」到「中斷:x = 9」之間的任何內容。
請注意,從 退出之前恢復線程的中斷標誌被認爲是一種好的做法,否則此run()
方法的調用方將看不到中斷狀態。
現在,如果它是至關重要的是,我們的任務完全執行,從而使輸出將始終以「X = 10」,這意味着任務不支持取消,我們需要另一種方法:
public void run() {
int x = 0;
boolean wasInterrupted = false; // <- This is the local variable to store the interruption status
while (x < 10) {
wasInterrupted = wasInterrupted || Thread.interrupted(); // not really needed in this case, but for the sake of completeness...
try {
Thread.sleep(1000); // <- Some interruptible operation
} catch (InterruptedException e) {
wasInterrupted = true;
}
x++;
}
System.out.println("x = " + x);
if (wasInterrupted) {
Thread.currentThread().interrupt();
}
}
在這種情況下,我們甚至在InterruptedException
之後繼續處理,直到任務完成。 爲了保持良好,如果我們檢測到中斷,我們將該條件存儲在wasInterrupted
中,以便我們可以在從該方法返回之前正確設置中斷標誌。
這就是由
意味着要在本地保存中斷狀態,只是在返回之前恢復。
它說,「應該」,因爲我們沒有嚴格要求來處理中斷這種方式 - 我們可能也只是忽略任何InterruptedException
,只是完成我們的任務,然後返回。但這並不是上面提到的良好做法,並且在某些情況下可能會造成麻煩。
這裏給出一個合理的解釋:http://stackoverflow.com/questions/7751690/noncancelable-task-that-restores-interruption-before-exit – Cole