由于线程的本质特性,使得你不能捕获从线程中逃逸的异常。一旦异常逃出任务的run()方法,它就会向外传播到控制台。
将main的主体放到try-catch也是没有用的。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
class ExceptionThread implements Runnable {
public void run() {
throw new RuntimeException();
}
}
//实现抓住异常
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("caught " + 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 + " ID:" + t.getId());
t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
System.out.println("eh=" + t.getUncaughtExceptionHandler());
return t;
}
}
public class CaptureUncaughtException {
public static void main(String[] args) {
ExecutorService exec = Executors
.newCachedThreadPool(new HandlerThreadFactory());
exec.execute(new ExceptionThread());
}
}
为了解决这个问题,我们要修改Executor产生线程的方式。Thread.UncaughtException-Handler是Java SE5中的新接口,它允许你在每个Thread对象上都附着一个异常处理器。Thread.UncaughtExceptionHandler.uncaughtException()会在线程因未捕获的异常而临近死亡时被调用。创建一个线程工厂实现ThreadFactory,在这个线程工厂给每个线程对象附着一个UncaughtExceptionHandler。再将这个工厂传递给Executors创建新的ExecutorService的方法。
这里的Thread-0这个线程我不清楚是main()产生的还是在new HandlerThreadFactory()的时候产生的?我认为是new HandlerThreadFactory()的时候产生的。
Thread源码还有更简单的方式设置未捕获异常处理器