/但是呢,在我们线程池中会重设置新的Thread对象,而这个Thread对象没有设置任何异常处理器,换句话说,我们在线程池外对线程做的
//任何操作都是没有用的
ExecutorService exec1 = Executors.newCachedThreadPool();
Runnable runnable = new ExceptionThread2();
Thread t1 = new Thread(runnable);
t1.setUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());
exec1.execute(runnable);
//第3种情况一样的,也是走的线程池,但是呢是通过ThreadFactory方式,在ThreadFactory中会对线程做一些控制,可以设置异常处理器
//此时是可以捕获异常的。
ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());
exec.execute(new ExceptionThread2());
}
}
运行结果
创建一个新的线程
eh121 = MyUnchecckedExceptionhandler@1b8e059
run() byThread[Thread-0,5,main]
eh=MyUnchecckedExceptionhandler@1b8e059
捕获到异常:java.lang.RuntimeException: 抛出运行时异常
从上述的运行结果中可以看到,未捕获的异常是通过uncaughtException来捕获的。
按照上述的实例,我们可以按照具体的情况,逐个地设置处理器。但是如果我们知道将要在代码的所有地方都是用相同的异常处理器,那么更简单的方式是在Thread类中设置一个静态域,并将这个处理器设置为默认的未捕获异常处理器。看下面的例子:
Thread.setDefaultUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());
ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());
exec.execute(new ExceptionThread2());
这个默认的处理器只有在线程不存在非默认的异常处理器时才会调用。 在运行时,系统会检查线程是否有属于自己的异常处理器,如果发现没有,就去检查相应的线程组是否有专有的异常处理器,如果发现也没有,再调用默认的异常处理器。