如果使用常規的try...catch來對從線程中拋出的異常進行處理
package Exception;public class ExceptionThread extends Thread{public void run(){throw new RuntimeException();}public static void main(String[] args){ExceptionThread thread = new ExceptionThread();try{thread.start();}catch (RuntimeException e) {System.out.println("handler the exception");}}}
運行上面代碼會得到java.lang.RuntimeException的提示,所以可以看見使用try..catch無法捕獲從線程中拋出的異常。
怎麼處理從線程中拋出的異常呢。這裡需要瞭解Thread類中的一個嵌套類Thread.UncaughtExceptionHandler,根據名字就可以看到是對Thread類中未捕獲異常進行處理的類。
api中的解釋public static interface Thread.UncaughtExceptionHandler當 Thread 因未捕獲的異常而突然終止時,調用處理常式的介面。 當某一線程因未捕獲的異常而即將終止時,JAVA 虛擬機器將使用 Thread.getUncaughtExceptionHandler() 查詢該線程以獲得其 UncaughtExceptionHandler 的線程,並調用處理常式的 uncaughtException 方法,將線程和異常作為參數傳遞。如果某一線程沒有明確設定其 UncaughtExceptionHandler,則將它的 ThreadGroup 對象作為其 UncaughtExceptionHandler。如果 ThreadGroup 對象對處理異常沒有什麼特殊要求,那麼它可以將調用轉寄給預設的未捕獲例外處理常式。
public class CatchThreadException{public static void main(String[] args){ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFacotry());exec.execute(new ThreadException());}}class ThreadException implements Runnable{public void run(){throw new RuntimeException();}}class MyThreadExceptionHandler implements UncaughtExceptionHandler{public void uncaughtException(Thread t, Throwable e){System.out.println("Exception handler");}}class HandlerThreadFacotry implements ThreadFactory{public Thread newThread(Runnable r){Thread thread = new Thread(r);thread.setUncaughtExceptionHandler(new MyThreadExceptionHandler());return thread;}}
運行上面代碼得到的結果是Exception handler ThreadException是一個實現Runnable介面的類,在其run方法中拋出一個異常,
Executors.newCachedThreadPool(new HandlerThreadFacotry())
我們實現一個線程池,並且指定產生線程的Factory 方法,在該Factory 方法裡面,我們每生產一個線程就調用Thread.setUncaughtExceptionHandler()為其指定異常處理handler,當線程拋出異常的時候,就會執行指定handler的uncaughtException()方法,參數由jdk自動傳入。