捕獲執行緒執行期間的異常
阿新 • • 發佈:2020-09-19
捕獲執行緒執行期間的異常
上一篇文章我們學習了在我們使用application的時候在他出現問題或者人為終止的時候,我們怎麼有機會捕獲異常或者人為的做一些操作,比如寫一些日誌,或者傳送一個RESTful或者關閉釋放一些資源,那麼執行緒執行期間的異常該如何捕獲呢?我們知道執行緒的執行邏輯單元在run方法裡,run方法的簽名是不允許丟擲異常的,今天我們就來學習一下執行緒的Exception。
先來一段丟擲異常的程式碼:
public class ThreadException { private final static int A = 10; private static final int B = 0; public static void main(String[] args) { /// 捕獲執行緒執行期間的異常 Thread t = new Thread(() -> { try { Thread.sleep(1_000L); int result = A / B; System.out.println("result = " + result); } catch (InterruptedException e) { e.printStackTrace(); } }); t.start(); } }
執行效果如下:
我們改造一下我們的程式碼,Thread物件提供了setUncaughtExceptionHandler
方法用來獲取執行緒中產生的異常。而且建議使用該方法為執行緒設定異常捕獲方法:
t.setUncaughtExceptionHandler((thread, e) -> { System.out.println(e); System.out.println(thread.getName()); System.out.println(thread.getThreadGroup().getName()); System.out.println(thread.getThreadGroup().getParent().getName()); });
執行效果如下:
可以看到異常的詳細堆疊資訊已經打印出來了,下面做個實驗來輸出一下,先建幾個類分別進行呼叫,如下:
public class ThreadException {
public static void main(String[] args) {
// stack trace
new Test1().test();
}
}
public class Test1 { private Test2 test2 = new Test2(); public void test() { test2.test(); } }
public class Test2 {
public void test() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
Stream.of(stackTrace)
.filter(e -> !e.isNativeMethod())
.forEach(e ->
Optional.of(e.getClassName() + "." + e.getMethodName() + ":" + e.getLineNumber())
.ifPresent(System.out::println)
);
}
}
執行效果如下:
這個在後續使用中有補充再繼續補充,後面開始學習ThreadGroupApI的學習,然後實現一個執行緒池,java併發程式設計的基礎就碼一遍了。