1. 程式人生 > >開發案例——執行緒池/任務未抓取異常處理

開發案例——執行緒池/任務未抓取異常處理

問題描述:

  1. 使用 java.util.TimerTask 任務中斷(遇到未抓取異常時後續任務不執行);

     2.  使用 java.util.concurrent.Executors.xxx 執行緒池對於未抓取異常無異常輸出,無法定位問題;

定位方法:

對比 TimerTask/Executors/Quartz 三者對丟擲異常的反應

TimerTask

Executors

Quartz

是否中斷後續任務

是否有異常輸出

是(uncaught)

是(log4j)

問題解決:

建議:

  1. 對於定時任務,建議使用 quartz 庫。(使用 TimerTask 有未抓取異常時會導致當前Timer終止,後續任務無法執行)
  2. 執行緒池有未抓取異常時不會導致後續任務中斷,但是沒有異常資訊的輸出,難以定位問題,對此,有三種方案:
    1. )自己封裝一個RunnableWrapper、CallableWrapper,將傳入的任務包裹其中,在run方法中try-catch,並統一對未抓取異常進行異常處理/輸出;
    2. )繼承ThreadPoolExecutor的方式來建立執行緒池,重寫其afterExecute(Thread, Throwable)方法,判斷第二個引數非空時獲得其異常資訊,統一進行處理;(注意:僅對 executor.execute(..) 啟動的任務有效,executor.submit(..)的無效)
    3. )建立執行緒池時,傳入自定義的ThreadFactory,在其建立執行緒時,使用setUncaughtExceptionHandler(..)設定每個執行緒的未抓取異常處理控制代碼,統一進行處理;(注意:僅對 executor.execute(..) 啟動的任務有效,executor.submit(..)的無效)