平时在开发过程中经常使用到线程,一个不注意就会出现RunTimeException, 导致线程不运行, 而且还没有log。感觉莫名其妙。
比如如下代码:
public static void main(String[] args) throws Exception {
Thread t = new Thread(() -> {
throw new RuntimeException("TTTTT");
}, "test");
t.start();
t.join();
TimeUnit.SECONDS.sleep(3);
System.out.println(1);
}
会出现一个
Exception in thread "test" java.lang.RuntimeException: TTTTT
at com.hjb.learning.jdk8.UncaughtExceptionHandlerMain.lambda$main$1(UncaughtExceptionHandlerMain.java:17)
at java.lang.Thread.run(Thread.java:748)
1
虽然最后母线程正常退出了,但是无法接收到子线程的异常。
很幸运的是, Thread类的设计者已经做了相应的处理。内部存在一个未捕获异常的处理器。
我们可以通过设置这个属性,然后JVM 会通过如下方法实现回调处理。
UncaughtExceptionHandler 是线程内部的一个方法接口。
简单做一个demo:
private static Thread.UncaughtExceptionHandler handler = (thread, e) -> {
System.out.println("------------error------------" + e.getMessage());
System.out.println(thread.getName());
};
public static void main(String[] args) throws Exception {
Thread t = new Thread(() -> {
throw new RuntimeException("TTTTT");
}, "test");
t.setUncaughtExceptionHandler(handler);
t.start();
t.join();
TimeUnit.SECONDS.sleep(3);
}
对应的输出:
------------error------------TTTTT
test
这样子线程的异常可以反馈到handler里面,这样就可以实现在母线程中处理子线程的异常了。
这边值得学习的是:handler回调处理的思想, 这个实现在jdk8 lambda表达式出来之后,应用非常广泛了