在Java中,線程池中工作線程出現異常的時候,默認會把異常往外拋,同時這個工作線程會因爲異常而銷燬,我們需要自己去處理對應的異常,異常處理的方法有幾種:
-
在傳遞的任務中去處理異常,對於每個提交到線程池中的執行的任務,可以提前通過異常進行捕獲,這樣即便出現了異常,也不會影響線程池中的工作線程
-
使用Future來捕獲異常結果,在線程池中提供了一個submit(Callable<T>)方法,這個方法會返回一個Future,可以通過調用Future.get()方法,來獲取任務的執行結果,如果任務執行過程中出現了異常,也會拋出一個ExecutionException,其中就包含了任務執行過程中出現的異常
-
我們還可以自定義一個ThreadFactory,設置一個UncaughtExceptionHandler,我們可以通過實現ThreadFactory的接口來自定義創建線程的方式,然後爲每個新創建的線程設置一個UncaughtExceptionHandler,這個處理器會在線程由於未捕獲異常而即將終止的時候被調用
下面是三段代碼示例:
捕獲線程執行異常
ExecutorService executorService = Executors.newFixedThreadPool(5); executorService.execute(() -> { try { // 執行任務 } catch (Exception e) { // 記錄日誌 logger.error("An exception occurred: ", e); } });
在執行任務的過程中,如果出現異常,就會被try-catch語句捕獲,並將異常信息記錄到日誌中。
使用Future來捕獲異常結果
ExecutorService executorService = Executors.newFixedThreadPool(5); List<Future<?>> futures = new ArrayList<>(); // 提交任務到線程池 for (int i = 0; i < 10; i++) { Future<?> future = executorService.submit(() -> { // 執行任務 }); futures.add(future); } // 獲取任務結果 for (Future<?> future : futures) { try { future.get(); } catch (InterruptedException | ExecutionException e) { // 處理異常 logger.error("An exception occurred: ", e); } }
在這個例子中,我們將多個任務提交到線程池,並將每個任務的Future對象保存在futures列表中。接着,我們遍歷futures列表,並調用每個Future對象的get()方法來獲取任務的執行結果。如果任務執行過程中出現了異常,則會拋出ExecutionException異常,我們在catch塊中捕獲該異常並進行相應的處理。
實現UncaughtExceptionHandler接口
public class CustomExceptionHandler implements Thread.UncaughtExceptionHandler { @Override public void uncaughtException(Thread t, Throwable e) { // 記錄日誌或者進行其它處理 logger.error("Thread " + t.getName() + " encountered an exception: ", e); } } ExecutorService executorService = Executors.newFixedThreadPool(5); // 設置UncaughtExceptionHandler ((ThreadPoolExecutor) executorService).setThreadFactory(r -> { Thread thread = new Thread(r); thread.setUncaughtExceptionHandler(new CustomExceptionHandler()); return thread; }); executorService.execute(() -> { // 執行任務 });
這種方式需要自定義一個實現了UncaughtExceptionHandler接口的異常處理器,當線程出現異常時,異常處理器會被調用,我們可以在其中記錄日誌或者進行其它處理。接着,我們需要將異常處理器設置到線程池的線程工廠中。當線程池內的線程出現異常時,異常處理器就會被調用,我們可以在其中處理異常。