[英]App Engine continues program execution despite throwing BadRequestException
[英]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
退出整個方法ScheduledExecutorService
並從Runnable
的運行方法中刪除循環,使任務成為重復任務“除了盡力停止處理正在執行的任務之外,沒有任何保證。例如,典型的實現將通過 Thread.interrupt() 取消,因此如果任何任務屏蔽或未能響應中斷,它們可能永遠不會終止。”
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.