在 Java 中,主線程的 try-catch 無法捕捉子線程拋出的異常。Thread 類別提供 setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler) 方法,允許開發者為特定線程或全域設定未捕獲異常處理器,確保異常不會悄無聲息地被忽略。
Thread.setUncaughtExceptionHandler(UncaughtExceptionHandler eh):為當前線程實例設定處理器。Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh):設定全域預設處理器(影響所有未自行設定處理器的線程)。UncaughtExceptionHandler 單一方法:void uncaughtException(Thread t, Throwable e)。package threads;
import java.lang.Thread.UncaughtExceptionHandler;
public class ThreadExceptionDemo {
public static void main(String[] args) {
// 建立子線程
TestThread test = new TestThread();
// 為該線程單獨設定異常處理器
test.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("線程 [" + t.getName() + "] 發生未捕獲異常: " + e.getMessage());
e.printStackTrace(); // 可在此記錄日誌、發送告警等
}
});
test.start(); // 啟動線程
}
static class TestThread extends Thread {
@Override
public void run() {
// 模擬業務邏輯拋出運行時異常
throw new RuntimeException("測試子線程異常捕獲");
}
}
}
線程 [Thread-0] 發生未捕獲異常: 測試子線程異常捕獲
java.lang.RuntimeException: 測試子線程異常捕獲
at threads.ThreadExceptionDemo$TestThread.run(ThreadExceptionDemo.java:28)
Thread.setDefaultUncaughtExceptionHandler(...),統一處理所有未設定專屬處理器的線程異常,適合框架層級錯誤收集。ThreadFactory 建立線程時,在 newThread(Runnable r) 中為每個線程設定處理器,確保池內線程異常皆被捕獲。uncaughtException 中結合 MDC(Mapped Diagnostic Context)記錄請求 ID、用戶資訊等上下文,利於事後追蹤。try-catch 包住 thread.start() 即可捕獲子線程異常 —— 實際上 start() 會立即返回,異常發生在新線程堆疊中。