Java中斷異常 InterruptedException 的正確處理方式


你看到這篇文件可能是因為你已經調用了一個拋出 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, 你應該(必須!)捕獲異常。在這種情況下,現在要記住兩件事:
  1. 有人打斷了你的線程。這個人可能急於取消操作,優雅地終止程序,或者其他什么。你應該對那個人保持禮貌並且不用再費力地從你的方法中返回。
  2. 即使你的方法可以設法讓出現 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; } 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM