由于线程本质特性,使得我们不能捕获从线程中逃逸的异常。一旦异常逃出线程的run方法,他就会向外传播到控制台。
捕获线程中异常分为以下几步:
新建线程异常处理器,实现Thread.UncaughtExceptionHandler接口
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("catch " + e);
}
}
创建线程工厂,给每一个由此工厂生产的线程都设置线程处理器:
class HandlerThreadFactory implements ThreadFactory{
@Override
public Thread newThread(Runnable r) {
System.out.println(this+" creating new Thread");
Thread t = new Thread(r);
System.out.println(" created " + t);
//设置线程处理器
t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
System.out.println("eh= "+t.getUncaughtExceptionHandler());
return t;
}
}
创建线程:
class ExceptionThread implements Runnable{
@Override
public void run() {
Thread t = Thread.currentThread();
System.out.println("run() by "+ t);
System.out.println("eh= " +t.getUncaughtExceptionHandler());
throw new RuntimeException();
}
}
使用测试:
public class CaptureUnCaughtException {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());
exec.execute(new ExceptionThread());
}
}
输出(不一定完全一样):
com.len.javabase.supervene.base.HandlerThreadFactory@4e25154f creating new Thread
created Thread[Thread-0,5,main]
eh= com.len.javabase.supervene.base.MyUncaughtExceptionHandler@70dea4e
run() by Thread[Thread-0,5,main]
eh= com.len.javabase.supervene.base.MyUncaughtExceptionHandler@70dea4e
com.len.javabase.supervene.base.HandlerThreadFactory@4e25154f creating new Thread
created Thread[Thread-1,5,main]
eh= com.len.javabase.supervene.base.MyUncaughtExceptionHandler@471be934
catch java.lang.RuntimeException