簡體   English   中英

為什么Thread.sleep()清除中斷的標志?

[英]WHY does Thread.sleep() clear the interrupted flag?

我知道一些Thread方法清除了中斷的標志(例如,睡眠,等待......)。 但為什么他們這樣做? 它是什么原因?

這是因為中斷被設計為完全取消同義詞。 Oracle的指導是僅將中斷用於取消,但該視圖可能已經過時。 無論如何,設計並沒有強制這樣做。 您可以設計一個任務來響應中斷,然后回到它正在做的事情。

在Java Concurrency in Practice,7.1,第138頁中,它說:

API或語言規范中沒有任何內容將中斷與任何特定的取消語義聯系起來,但在實踐中,除了取消之外,使用中斷是非常脆弱的,並且在大型應用程序中可以維持。

它的設計方式在任何給定時間都有一件事,要么是被捕獲的InterruptedException,要么是中斷標志,以告訴線程的狀態。 如果InterruptedException正在進行中,則該標志的值無關緊要。 並且想法似乎是捕獲異常的代碼應該決定是否應該設置中斷的標志。

這樣,使用InterruptedException退出循環很方便:

try {
    while (!Thread.currentThread().isInterrupted()) {
        Thread.sleep(5000);
        // ... do stuff ...
    }
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
}

這里線程停止循環,因為異常被捕獲到循環外部,只關系中斷標志是否設置,這對任何周圍的代碼都很重要。 但是,如果您在循環中捕獲InterruptedException,例如:

while (!Thread.currentThread().isInterrupted()) {
    // ... do stuff ...
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

(而且很多代碼都是這樣做的,因為程序員已經把它們弄得腦子里,他們甚至不應該考慮使用流控制的異常),然后你必須設置中斷的標志。

我認為目的是應用程序開發人員應該使用異常來逃避中斷的上下文,吃掉接近源的異常並不干凈。

簡而言之,因為這些方法將線程發送到“新鮮”等待狀態(在它被中斷回到運行狀態之后)。 先前設置的“中斷”標志不再適用,因為線程自進入新的等待狀態后未被中斷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM