摘要:首先,需要了解為一個方法為啥會是這個方法拋出中斷異常作為方法簽名的一部分以及調用正在調用的方法的可能結果。到目前為止,應該清楚的是,做這件事是一個壞主意。選擇不同的接口,例如則可以拋出中斷異常,或者按照說的上面的第二種方法。
你看到這篇文件可能是因為你已經調用了一個拋出 InterruptedException 異常的方法,并且需要以某種方式處理它。
首先,需要了解為一個方法為啥會 throws InterruptedException, 是這個方法拋出中斷異常作為方法簽名的一部分以及調用正在調用的方法的可能結果。因此,首先要接受一個事實,InterruptedException 是這個方法調用的完全有效的結果。
現在,如果你正在調用的方法拋出此類異常,你的方法應該怎么做?可以通過考慮以下問題找出答案:
你正在實現的方法是否有意義拋出異常 InterruptedException?換句話說,InterruptedException 異常是否是調用你的方法是一個明智的結果?
如果是,那么 throws InterruptedException 應當成為你的方法簽名,你應該讓異常傳播(即不捕獲該異常的話)。
示例: 你的方法等待來自網絡的值以完成計算并返回結果。如果阻塞網絡調用拋出 InterruptedException方法無法以正常方式完成計算。你讓 InterruptedException 傳播。
int computeSum(Server server) throws InterruptedException { // Any InterruptedException thrown below is propagated int a = server.getValueA(); int b = server.getValueB(); return a + b; }
如果不是,那么你不應該聲明你的方法 throws InterruptedException, 你應該(必須!)捕獲異常。在這種情況下,現在要記住兩件事:
有人打斷了你的線程。這個人可能急于取消操作,優雅地終止程序,或者其他什么。你應該對那個人保持禮貌并且不用再費力地從你的方法中返回。
即使你的方法可以設法讓出現 InterruptedException 異常時, 即在線程被中斷的情況下, 產生合理的返回值,線程被中斷過這件事仍然很重要。特別是,調用方法的代碼可能會對執行方法期間是否發生中斷感興趣。您應該通過設置中斷標志來記錄發生中斷的事實:即需要在 catch 里調用Thread.currentThread().interrupt() .
示例: 用戶要求打印兩個值的總和。如果無法計算總和,則打印“無法計算總和”(并且比由于一個導致程序因堆棧跟蹤而崩潰要好得多 InterruptedException)。換句話說,用這個方法聲明這個方法是沒有意義的throws InterruptedException。
void printSum(Server server) { try { int sum = computeSum(server); System.out.println("Sum: " + sum); } catch (InterruptedException e) { Thread.currentThread().interrupt(); // set interrupt flag System.out.println("Failed to compute sum"); } }
到目前為止,應該清楚的是,做這件事throw new RuntimeException(e)是一個壞主意。這對調用者來說不太禮貌。您可以發明一個新的運行時異常,但根本原因(某人希望線程停止執行)可能會丟失。
另一個例子:實施 Runnable
正如您可能已經發現的那樣,簽名 Runnable.run 不允許重新拋出 InterruptedExceptions。好吧,你聲明了實現 Runnable 接口,這意味著你已聲明處理可能的中斷異常問題。選擇不同的接口,例如Callable則可以拋出中斷異常(V call() throws Exception),或者按照說的上面的第二種方法。
還有一個:調用 Thread.sleep
你正在嘗試讀取文件,規范說你應該嘗試10次,間隔1秒。調用 Thread.sleep(1000)。所以,你需要處理 InterruptedException。對于一種方法 tryToReadFile 來說,如果說“如果我被打斷了,我無法完成嘗試閱讀文件的行為”這一方法非常有意義。換句話說,它對拋出的方法很有意義InterruptedExceptions。
String tryToReadFile(File f) throws InterruptedException { for (int i = 0; i < 10; i++) { if (f.exists()) return readFile(f); Thread.sleep(1000); } return null; }
作者:
Andreas Lundblad,理論計算機科學博士。在Oracle開發Java平臺(javac,javadoc,sjavac)工作了三年。安德烈亞斯是StackOverflow的Java標簽的前10貢獻者.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/72633.html
摘要:當線程執行完后進入狀態,表示線程執行結束。其中和表示兩個線程。但要注意,讓出并不表示當前線程不執行了。關鍵字其作用是防止指令重排和使線程對一個對象的修改令其他線程可見。 JMM特性一覽 Java Memory Model的關鍵技術點都是圍繞著多線程的原子性、可見性和有序性來建立的。因此我們首先需要來了解這些概念。 原子性(Atomicity) 原子性是指一個操作是不可中斷的。即使是在多...
摘要:中斷線程當線程的方法方法體執行完畢自然終止或在方法中出現沒有捕獲的異常時意外終止,線程將終止。如果被中斷線程被阻塞,就無法檢測中斷狀態,就會產生異常。 多進程與多線程的本質區別在于:每個進程擁有自己的一整套變量,而線程則共享數據。如果需要執行一個比較耗時的任務,應該使用獨立的線程。 可以通過實現Runnable接口或繼承Thread類來創建獨立的線程。 1) 實現Ruannable接口...
摘要:程序執行時,至少會有一個線程在運行,這個運行的線程被稱為主線程。程序的終止是指除守護線程以外的線程全部終止。多線程程序由多個線程組成的程序稱為多線程程序。線程休眠期間可以被中斷,中斷將會拋出異常。 線程 我們在閱讀程序時,表面看來是在跟蹤程序的處理流程,實際上跟蹤的是線程的執行。 單線程程序 在單線程程序中,在某個時間點執行的處理只有一個。 Java 程序執行時,至少會有一個線程在運行...
摘要:正確方法通過中斷來取消線程。小結調用并不意味著立即停止目標線程正在進行的工作,而只是傳遞了請求中斷的消息。在使用靜態的時應該小心,因為它會清除當前線程的中斷狀態。 序 本文展示一個常見的取消線程的方法。 錯誤實例 class BrokenPrimeProducer extends Thread { private final BlockingQueue queue; p...
摘要:現在終止一個線程,基本上只能靠曲線救國式的中斷來實現。中斷機制的核心在于中斷狀態和異常中斷狀態設置一個中斷狀態清除一個中斷狀態方法同時會返回線程原來的中斷的狀態。中斷異常中斷異常一般是線程被中斷后,在一些類型的方法如中拋出。 前言 系列文章目錄 線程中斷是一個很重要的概念,通常,取消一個任務的執行,最好的,同時也是最合理的方法,就是通過中斷。 本篇我們主要還是通過源碼分析來看看中斷的概...
閱讀 1994·2021-11-15 18:09
閱讀 889·2021-09-06 15:13
閱讀 2636·2021-08-23 09:43
閱讀 2016·2019-08-30 15:54
閱讀 2208·2019-08-30 13:56
閱讀 2476·2019-08-26 11:31
閱讀 3069·2019-08-26 10:56
閱讀 685·2019-08-26 10:28