簡體   English   中英

盡管出現了 InterruptedException,程序仍繼續運行

[英]Program continues to run despite InterruptedException

我開始學習 java,現在我在並發章節。 在閱讀了一些關於並發的東西之后,我嘗試了一個我自己的例子。

public class Task implements Runnable{

public void run() {
    while(!Thread.interrupted()) {
        try {
            System.out.println("task");
            TimeUnit.SECONDS.sleep(2);
        }catch (InterruptedException e) {
            System.out.println("interrupted");
        }
    }
}

}

public static void main(String[] args) throws Exception {
    ExecutorService exec = Executors.newCachedThreadPool();
    exec.execute(new Task());
    TimeUnit.SECONDS.sleep(10);
    exec.shutdownNow();
}

問題是我期待看到以下 output:

task
task
task
task
task
interrupted

但是在我得到這個之后,程序會繼續打印,直到我關閉它。
所以,我的問題是我做錯了什么? 為什么程序繼續打印?

當您關閉執行程序時,它會嘗試通過中斷正在運行的任務來停止它們。 這會導致拋出 InterruptedException,但您只需將其吞下並繼續。 您應該在 catch 子句中返回,和/或通過調用Thread.currentThread.interrupt()來重置線程的中斷狀態,這將重置中斷狀態並退出循環。

您仍在 while 循環中,添加一個中斷或其他方式退出循環。

    catch (InterruptedException e) {
        System.out.println("interrupted");
        break;
    }

Java 中的線程是一種合作活動,你被要求停止,但你需要足夠禮貌才能真正做到這一點。 這允許線程有時間在其消亡之前整理其事務。

正如 Simon 和 Amir 詳細解釋的那樣,您的循環終止條件令人驚訝地不充分。

Java關於並發的教程中關於中斷的部分很好地解釋了這個問題:

中斷狀態標志

中斷機制是使用稱為中斷狀態的內部標志來實現的。 調用 Thread.interrupt 設置此標志。 當線程通過調用 static 方法 Thread.interrupted 檢查中斷時,中斷狀態被清除。 一個線程用來查詢另一個線程的中斷狀態的非靜態 isInterrupted 方法不會改變中斷狀態標志。

按照慣例,任何通過拋出 InterruptedException 退出的方法都會在這樣做時清除中斷狀態。 然而,中斷狀態總是有可能被另一個線程調用中斷立即再次設置。

因此,當您在循環中捕獲 InterruptedException 時,中斷狀態已經被重置,因此,下一次調用 Thread.interrupted() 將返回 false,從而使 while 循環繼續運行。 要停止循環,您有以下選項:

  • 使用break退出循環
  • 使用return退出整個方法
  • 將 try-catch-block 移到 while 循環之外(如 Nathan Hughes 建議的那樣)
  • 在當前線程上調用interrupt()再次設置中斷標志
  • 使用單獨的 boolean 來控制循環並在 catch-block 中相應地設置該標志
  • 通過使用ScheduledExecutorService並從Runnable的運行方法中刪除循環,使任務成為重復任務

“除了盡力停止處理正在執行的任務之外,沒有任何保證。例如,典型的實現將通過 Thread.interrupt() 取消,因此如果任何任務屏蔽或未能響應中斷,它們可能永遠不會終止。”

來源: http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ExecutorService.html#shutdownNow ()

暫無
暫無

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

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