如果在java中定义了如下的类,希望在多线程环境下,捕获异常
static class myRun implements Runnable {
@Override
public void run() {
System.out.println("myRun.run()");
throw new RuntimeException();
}
}
那么通过如下两种方式,是不能在调用这两个线程的程序中,捕获到异常的。
try {
new Thread(new myRun()).start();
} catch (Exception e) {
// TODO: handle exception
System.out.println("caught exception in main");
}
try {
Executors.newCachedThreadPool().execute(new myRun());
} catch (Exception e) {
// TODO: handle exception
System.out.println("caught exception in main");
}
在Java中,如果要捕获线程中的异常,需要通过UncaughtExceptionHandler实现。
UncaughtExceptionHandler是一个接口,只有一个方法:
void uncaughtException(Thread t, Throwable e)
当给定线程因给定的未捕获异常而终止时,调用该方法。
所以,如果希望捕获线程的异常,我们可以实现UncaughtExceptionHandler:
static class myUncaughtExceprionHandler implements UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
// TODO Auto-generated method stub
System.out.println("caughtException in my handler");
System.out.println(e);
}
}
然后,在线程开始之前,设置线程的uncaughtExceptionHandler:
Thread thread = new Thread(new myRun());
thread.setUncaughtExceptionHandler(new myUncaughtExceprionHandler());
thread.start();
但是,在使用线程池的时候,问题来了,到底应该在哪设置uncaughtExceptionHandler?
这时候,需要自定义一个新的ThreadFactory:
static class HandlerThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setUncaughtExceptionHandler(new myUncaughtExceprionHandler());
return t;
}
}
然后通过如下方式运行程序:
ExecutorService exe = Executors.newCachedThreadPool(new
HandlerThreadFactory());
exe.execute(new myRun());