线程的未捕获异常UncaughtException应该如何处理?
为什么需要UncaughtExceptionHandler?
- 主线程可以轻松发现异常,子线程却不行;
- 子线程异常,无法用传统方法进行捕获;
代码演示:
/** 单线程,抛出,处理,有异常堆栈
多线程,子线程发送异常,会有什么不同
* */
public class ExceptionInChildThread implements Runnable{
@Override
public void run() {
throw new RuntimeException();
}
public static void main(String[] args) {
new Thread(new ExceptionInChildThread()).start();
for(int i = 0; i < 1000; i++){
System.out.println(i);
}
}
}
输出:

1.不加try catch 抛出4个异常,都带线程名字;
2.加了try catch,期望捕获到第一个线程的异常,线程234不应该运行,希望看到打印出Caught Exception;
3.执行时发现,根本没有Caught Exception,线程234依然运行,并且抛出异常 说明线程的异常不能用传统方法捕获。
代码演示:
public class CantCatchDirectly implements Runnable{
@Override
public void run() {
throw new RuntimeException();
}
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){
System.out.println("Caught Exception.");
}
}
}
输出结果;

此处try catch是针对主线程的,没有办法捕捉的子线程的异常,所以这里传统方法失效。
推荐解决方法:利用UncaughtExceptionHandler
- UncaughtExceptionHandler接口
- void uncaughtException(Thread t, Throwable e);
这里给程序设置统一的异常捕获:
分别新建两个类,UseOwnUncaughtExceptionHandler.java ,MyUncaughtExceptionHandler.java。
代码如下:
import java.util.logging.Level;
import java.util.logging.Logger;
/** 自行设置的 MyUncaughtExceptionHandler */
public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
private String name;
public MyUncaughtExceptionHandler(String name) {
this.name = name;
}
/** 传入参数:
Thread t:产生异常的线程;
Throwable e:具体的异常信息
* */
@Override
public void uncaughtException(Thread t, Throwable e) {
Logger logger = Logger.getAnonymousLogger();
logger.log(Level.WARNING," 线程异常,已终止 "+t.getName(),e);
System.out.println(name + "捕获了异常" + t.getName() + "异常" + e);
}
}
/** 使用刚才自己写的UncaughtExceptionHandler */
public class UseOwnUncaughtExceptionHandler implements Runnable{
@Override
public void run() {
throw new RuntimeException();
}
public static void main(String[] args) throws InterruptedException {
Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler("异常捕获器1"));
new Thread(new UseOwnUncaughtExceptionHandler(),"MyThread-1").start();
Thread.sleep(300);
new Thread(new UseOwnUncaughtExceptionHandler(),"MyThread-2").start();
Thread.sleep(300);
new Thread(new UseOwnUncaughtExceptionHandler(),"MyThread-3").start();
Thread.sleep(300);
new Thread(new UseOwnUncaughtExceptionHandler(),"MyThread-4").start();
}
}
运行UseOwnUncaughtExceptionHandler.java:

run()方法本身方法声明的时候,没有声明抛出异常,所以在方法层面,我们只能自己去做try catch处理。
本文探讨了如何处理线程未捕获异常UncaughtException,指出子线程异常不能用传统方法捕获,并推荐使用UncaughtExceptionHandler。通过代码示例展示了如何实现自定义的异常处理器。
1159

被折叠的 条评论
为什么被折叠?



