當一個線程因爲未捕獲的異常而退出時,JVM會將這個異常交給UncaughtExceptionHandler(異常處理器)來處理,如何沒有設置異常處理器,會將異常信息輸出到System.err。多線程環境下,其他線程仍然在輸出日誌,System.err輸出的異常信息很可能被忽略。可以通過設置UncaughtExceptionHandler,將未捕獲的異常信息保存到指定的日誌文件中。
1.首先實現Thread.UncaughtExceptionHandler接口
package com.yuanyk.uncaughtExceptionHandler;
public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("thread-->"+t.getName()+" get uncCatchException:"+e.getMessage());
}
}
2.測試Thread.start()
private static void testThread(){
Thread t = new Thread(() -> {
int i = 1/0;
});
t.setName("test thread");
t.start();
}
此時沒有設置UncaughtExceptionHandler,運行結果如下:
添加異常處理器後:
private static void testThread(){
Thread t = new Thread(() -> {
int i = 1/0;
});
t.setName("test thread");
t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
t.start();
}
3.測試線程池的execute()
需要在線程池的構造方法中傳入ThreadFactory,在ThreadFactory.newThread(Runnable r)方法中設置異常處理器
private static void testExector(){
ExecutorService executor = Executors.newFixedThreadPool(3, new ThreadFactory() {
AtomicInteger index = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, " thread-"+index.incrementAndGet());
thread.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
return thread;
}
});
executor.execute(() -> {int i = 1/0;});
executor.execute(() -> {int i = 1/0;});
executor.shutdown();
}
運行結果
4.測試線程池的submit()
private static void testSubmit(){
ExecutorService executor = Executors.newFixedThreadPool(3, new ThreadFactory() {
AtomicInteger index = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, " thread-"+index.incrementAndGet());
thread.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
return thread;
}
});
Future<String> future = executor.submit(() -> {return 1/0+"";});
try {
System.out.println(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
executor.shutdown();
}