線程的異常捕獲與線程池的異常捕獲


#(前言)

最近在做一些東西的時候,時常需要使用多線程來提升一下性能,但是在使用線程池的時候會發現無法捕獲其中線程的異常,這個該如何處理呢,talk is chep show me the code

#(單線程情況)

對於單線程來說,只需要重寫UncaughtException就好了,如下:

/**
 * Author: scw
 * Time: 16-11-24
 */
public class RewriteUncatchtExceptionHandler implements Thread.UncaughtExceptionHandler{
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("我捕獲到了線程池的異常");
    }
}
/**
 * Author: scw
 * Time: 16-11-24
 */
public class Task implements Runnable {
    public void run() {
        System.out.println("執行任務");
        int num  = Integer.parseInt("TT");
    }
}
/**
     * 對於單個線程出現的異常情況可以使用異常處理器,可以捕獲到
     */
    public static void catchSingleThread() {
        Task task = new Task();
        Thread thread = new Thread(task);
        thread.setUncaughtExceptionHandler(new RewriteUncatchtExceptionHandler());
     thread.start();
}

  運行程序,我們發現可以正常的捕獲到這個unchecked異常,但是線程池中我們應該怎么處理呢?如下:

#(線程池)

首先我們要重寫 ThreadFactory來為每個線程實例化的時候創建一個handler

/**
 * Author: scw
 * Time: 16-11-24
 */
public class MyThreadFactory implements ThreadFactory{
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r);
        t.setUncaughtExceptionHandler(new RewriteUncatchtExceptionHandler());
        System.out.println("Thread[" + t.getName() + "] created.");
        return t;
    }
}

  

  /**
     * 雖然從寫ThreadFactory以后,可以捕獲到異常,但是只能是execute,而submit還是不行  how to choose one
     */
    public static void catchedExecutor() {
        ExecutorService executorService = Executors.newCachedThreadPool(new MyThreadFactory());
        executorService.execute(new Task());
        executorService.shutdownNow();
    }

  現在問題來了,就是這樣雖然可以捕獲到異常,但是只能是使用execute的時候可以,使用submit的時候是不成功的,那么我們應該如何選擇呢?

/**
 * how to choose submit() or execute()
 * There is a difference concerning exception/error handling.A task queued with execute() that generates some Throwable will cause the UncaughtExceptionHandler
 * for the Thread running the task to be invoked. The default UncaughtExceptionHandler, which typically prints the Throwable stack trace to System.err, will be
 * invoked if no custom handler has been installed.On the other hand, a Throwable generated by a task queued with submit() will bind the Throwable to the Future
 * that was produced from the call to submit(). Calling get() on that Future will throw an ExecutionException with the original Throwable as its cause (accessible
 * by calling getCause() on the ExecutionException).
 * Author: scw
 * Time: 16-11-24
 */

  意思就是說二者最大的區別就是異常處理上,在execute的時候,如果你沒有實現一個handler,那么他就使用默認的handler來處理異常,你要是實現了一個handler

他就會使用的實例化的handler,但是對於submit來說,異常是綁定到Future上了,但是調用future.get()的時候,這些異常才會給你拋出來,意味着你自己定義的handler

其實是無效的

 

最后,如果大家有什么好的想法可以留言給我

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM