## 1、Thead.UncaughtExceptionHandler 捕获异常
在实现Runnable或者继承Thread类实现多线程的时候,都要实现或者重写run()方法,查看源码可以看到run()是不允许抛出异常的,那么如果在run()方法中产生了运行时异常如何捕获呢?
Thread类中有UncaughtExceptionHandler这个接口来实现对异常的捕获,我们只需将其方法重写,创建这个实现类的实例O,在线程start之前,使用thread.setUncaughtExceptionHandler(O)将这个实例传入此方法。下面直接看例子。如果在将第四行代码注释掉后可以发现直接抛出异常,无法捕获异常,即使你在主函数中用try,catch捕获也是会直接抛出异常的。
如果是继承了Thread.UncaughtExceptionHandler,并重写其中的方法,并且在目标线程中设置thread.setUncaughtExceptionHandler(),才能够去捕获线程中run方法的异常。
如果注释掉thread.setUncaughtExceptionHandler()的代码,可以看到
2、如果是线程池的话,定义线程工厂设置捕获异常
/*
- 第一步:定义符合线程异常处理器规范的“异常处理器”
- 实现Thread.UncaughtExceptionHandler规范
/
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
/- Thread.UncaughtExceptionHandler.uncaughtException()会在线程因未捕获的异常而临近死亡时被调用
*/
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("caught "+e);
}
}
复制代码
- Thread.UncaughtExceptionHandler.uncaughtException()会在线程因未捕获的异常而临近死亡时被调用
2.定义使用该异常处理器的线程工厂
复制代码
/*
- 第二步:定义线程工厂
- 线程工厂用来将任务附着给线程,并给该线程绑定一个异常处理器
*/
class HanlderThreadFactory implements ThreadFactory{
@Override
public Thread newThread(Runnable r) {
System.out.println(this+“creating new Thread”);
Thread t = new Thread®;
System.out.println("created "+t);
t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());//设定线程工厂的异常处理器
System.out.println(“eh=”+t.getUncaughtExceptionHandler());
return t;
}
}
复制代码
3.定义一个任务,让其抛出一个异常
复制代码
/*
- 第三步:我们的任务可能会抛出异常
- 显示的抛出一个exception
*/
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();
}
}
复制代码
4.调用实验
复制代码
/*
- 第四步:使用线程工厂创建线程池,并调用其execute方法
*/
public class ThreadExceptionUncaughtExceptionHandler{
public static void main(String[] args){
ExecutorService exec = Executors.newCachedThreadPool(new HanlderThreadFactory());
exec.execute(new ExceptionThread());
}
}