文章目录
方法一: 手动在每个run方法中进行try catch
- 方法一: 手动在每个run方法中进行try catch
- 方法二: 使用UncaughtExceptionHandler
- Java异常处理器的调用策略
如下的代码示例中, 就是在子线程中, 进行异常的捕获
package com.thread.uncaughtexception;
public class CantCatchDirectly implements Runnable{
public static void main(String[] args) throws InterruptedException {
//try {
new Thread(new CantCatchDirectly(),"MyThread-1").start();
Thread.sleep(300);
new Thread(new CantCatchDirectly(),"MyThread-2").start();
Thread.sleep(300);
new Thread(new CantCatchDirectly(),"MyThread-3").start();
Thread.sleep(300);
new Thread(new CantCatchDirectly(),"MyThread-4").start();
//} catch (RuntimeException e) {
// e.printStackTrace();
//}
}
@Override
public void run() {
try {
throw new RuntimeException();
} catch (RuntimeException e) {
// e.printStackTrace();
System.out.println(" 捕获了异常 ");
}
}
}
打印如下 这样做的弊端就是在每一个run方法中, 都要去捕获异常, 并且还要判断其异常的类型, 这样做效率太低.
通过如下的源码可以看到UncaughtExceptionHandler接口为Thread类的内部接口, 并且只有一个方法.返回值为void . 参数为两个, 一个是线程 ,一个是异常. 代表是哪个线程 ,抛了哪个异常信息.
异常处理器的源码如下: 主要的逻辑是: 首先检查是否有父线程, 如果有的话, 就用父线程的方法. 就是下面源码的parent.uncaughtException(t,e)
这个方法其实是本身, 就是递归调用. 会一直找到最顶层的ThreadGroup的异常处理器.
如果找到顶层的过程中,还是没有线程去处理, 那么就会进入到else的部分. 在else的部分, 会调用Thread.getDefaultUncaughtExceptionHandler. 如果没有实现UncaughtExceptionHandler这个接口, 那么获取的就是null ,则直接输出异常堆栈信息. 如果获取的不为空, 那么就会根据用户写的代码的实现, 去进行异常的处理 .