由于线程的特殊,使得你不能捕获从线程种逃逸的异常,在这里可以使用Executor来解决这个问题:
下面的代码没有办法捕获异常:
class ExceptionThread extends Thread {
@Override
public void run() {
super.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 service = Executors.newCachedThreadPool();
try {
service.execute(new ExceptionThread());
} catch (Exception e) {
System.out.println("catched : " +e);
}
}
}
Exception in thread "pool-1-thread-1" run by: Thread[pool-1-thread-1,5,main]
eh java.lang.ThreadGroup[name=main,maxpri=10]
java.lang.RuntimeException
at com.yaoqiang.demo.Thread.ExceptionThread.run(CaptureUncaughtException.java:14)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
RuntimeExeception 在主线程种没有办法被捕获到:
提供的解决办法:
class ExceptionThread extends Thread {
@Override
public void run() {
super.run();
Thread t = Thread.currentThread();
System.out.println("run by: " + t);
System.out.println("eh " + t.getUncaughtExceptionHandler());
throw new RuntimeException();
}
}
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) {
Thread t = new Thread(r);
System.out.println("create thread: " + t);
t.setUncaughtExceptionHandler( new
MyUncaughtExceptionHandler());
System.out.println("eh = " + t.getUncaughtExceptionHandler());
return t;
}
}
public class CaptureUncaughtException {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool(new HandlerThreadFactory());
try {
service.execute(new ExceptionThread());
} catch (Exception e) {
System.out.println("catched : " +e);
}
}
}
这是结果:
create thread: Thread[Thread-2,5,main]
eh = com.yaoqiang.demo.Thread.MyUncaughtExceptionHandler@40c929d0
catch java.lang.RuntimeException
创建一个ThreadFactory 为每个线程提供自己实现的Thread.UncaughtExceptionHandler ,不能捕获异常的处理器,这样在抛出异常的时候,就可以通过这个处理器来处理异常;如果所有线程使用相同的处理器,那么更加简单:main 方法替换:
public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
ExecutorService service = Executors.newCachedThreadPool();
try {
service.execute(new ExceptionThread());
} catch (Exception e) {
System.out.println("catched : " +e);
}
}