1.不能用传统方法捕获线程异常
public class CannotCatchDirectly implements Runnable {
@Override
public void run() {
throw new RuntimeException();
}
public static void main(String[] args) throws InterruptedException {
CannotCatchDirectly cannotCatchDirectly = new CannotCatchDirectly();
try {
Thread thread1 = new Thread(cannotCatchDirectly, "Thread1");
thread1.start();
Thread.sleep(1000);
Thread thread2 = new Thread(cannotCatchDirectly, "Thread2");
thread2.start();
Thread.sleep(1000);
Thread thread3 = new Thread(cannotCatchDirectly, "Thread3");
thread3.start();
Thread.sleep(1000);
Thread thread4 = new Thread(cannotCatchDirectly, "Thread4");
thread4.start();
Thread.sleep(1000);
} catch (RuntimeException exception) {
System.out.println(Thread.currentThread().getName() + "抛出异常");
}
}
}
程序执行结果如下所示,当Thread1抛出异常时,应当进入catch分支,并终止程序运行。但实际上没有,程序继续运行,4个子线程分别抛出异常,这说明使用try catch没有捕获到子线程异常。
Exception in thread "Thread1" java.lang.RuntimeException
at com.leichuangkj.threads.CannotCatchDirectly.run(CannotCatchDirectly.java:6)
at java.lang.Thread.run(Thread.java:748)
Exception in thread "Thread2" java.lang.RuntimeException
at com.leichuangkj.threads.CannotCatchDirectly.run(CannotCatchDirectly.java:6)
at java.lang.Thread.run(Thread.java:748)
Exception in thread "Thread3" java.lang.RuntimeException
at com.leichuangkj.threads.CannotCatchDirectly.run(CannotCatchDirectly.java:6)
at java.lang.Thread.run(Thread.java:748)
Exception in thread "Thread4" java.lang.RuntimeException
at com.leichuangkj.threads.CannotCatchDirectly.run(CannotCatchDirectly.java:6)
at java.lang.Thread.run(Thread.java:748)
2.UncaughtExceptionHandler源码分析
public class ThreadGroup implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
//默认情况下parent是null
if (parent != null) {
parent.uncaughtException(t, e);
} else {
//设置全局handler进行处理
Thread.UncaughtExceptionHandler ueh = Thread.getDefaultUncaughtExceptionHandler();
if (ueh != null) {
ueh.uncaughtException(t, e);
} else if (!(e instanceof ThreadDeath)) {
//全局handler不存在则输出异常堆栈
System.err.print("Exception in thread \"" + t.getName() + "\" ");
e.printStackTrace(System.err);
}
}
}
}
3.全局异常处理器
public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t.getName() + "捕获异常,异常信息" + e.toString());
}
}
public class CannotCatchDirectly implements Runnable {
@Override
public void run() {
throw new RuntimeException();
}
public static void main(String[] args) throws InterruptedException {
Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
CannotCatchDirectly cannotCatchDirectly = new CannotCatchDirectly();
Thread thread1 = new Thread(cannotCatchDirectly, "Thread1");
thread1.start();
Thread.sleep(1000);
Thread thread2 = new Thread(cannotCatchDirectly, "Thread2");
thread2.start();
Thread.sleep(1000);
Thread thread3 = new Thread(cannotCatchDirectly, "Thread3");
thread3.start();
Thread.sleep(1000);
Thread thread4 = new Thread(cannotCatchDirectly, "Thread4");
thread4.start();
Thread.sleep(1000);
}
}
程序执行结果如下所示,4个子线程抛出的异常都被捕获。
线程:Thread1捕获异常,异常信息为:java.lang.RuntimeException
线程:Thread2捕获异常,异常信息为:java.lang.RuntimeException
线程:Thread3捕获异常,异常信息为:java.lang.RuntimeException
线程:Thread4捕获异常,异常信息为:java.lang.RuntimeException