合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
# 捕获线程运行期间的异常 上一篇文章我们学习了在我们使用application的时候在他出现问题或者人为终止的时候,我们怎么有机会捕获异常或者人为的做一些操作,比如写一些日志,或者发送一个RESTful或者关闭释放一些资源,那么线程运行期间的异常该如何捕获呢?我们知道线程的运行逻辑单元在run方法里,run方法的签名是不允许抛出异常的,今天我们就来学习一下线程的Exception。 先来一段抛出异常的代码: ```java public class ThreadException { private final static int A = 10; private static final int B = 0; public static void main(String[] args) { /// 捕获线程运行期间的异常 Thread t = new Thread(() -> { try { Thread.sleep(1_000L); int result = A / B; System.out.println("result = " + result); } catch (InterruptedException e) { e.printStackTrace(); } }); t.start(); } } ``` 运行效果如下: ![](https://img.kancloud.cn/96/64/96641da4d88883720f51cc37420eee0e_856x228.gif) 我们改造一下我们的代码,Thread对象提供了`setUncaughtExceptionHandler`方法用来获取线程中产生的异常。而且建议使用该方法为线程设置异常捕获方法: ```java t.setUncaughtExceptionHandler((thread, e) -> { System.out.println(e); System.out.println(thread.getName()); System.out.println(thread.getThreadGroup().getName()); System.out.println(thread.getThreadGroup().getParent().getName()); }); ``` 运行效果如下: ![](https://img.kancloud.cn/a1/34/a13447f8c0fbb7d6b044a58d90b8ee27_856x228.gif) 可以看到异常的详细堆栈信息已经打印出来了,下面做个实验来输出一下,先建几个类分别进行调用,如下: ```java public class ThreadException { public static void main(String[] args) { // stack trace new Test1().test(); } } ``` ```java public class Test1 { private Test2 test2 = new Test2(); public void test() { test2.test(); } } ``` ```java public class Test2 { public void test() { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); Stream.of(stackTrace) .filter(e -> !e.isNativeMethod()) .forEach(e -> Optional.of(e.getClassName() + "." + e.getMethodName() + ":" + e.getLineNumber()) .ifPresent(System.out::println) ); } } ``` 运行效果如下: ![](https://img.kancloud.cn/e4/1e/e41e13d118730f1ba2236107dea0ced5_856x228.gif) 这个在后续使用中有补充再继续补充,后面开始学习ThreadGroupApI的学习,然后实现一个线程池,java并发编程的基础就码一遍了。