文章目录

  • 概述
  • 捕获线程运行时的异常
    • 使用场景
    • UncaughtExceptionHandler 接口
    • 示例
  • 获取调用链
  • 使用线程池的场景: 获取线程运行时异常

概述


捕获线程运行时的异常

我们看下Thread的定义 实现了Runnable接口

重写了run方法


根据方法签名可知,run方法是不能向上层抛出异常的,如果线程内部产生异常, 不catch的情况下,上层调用代码如何知道呢?


使用场景

为啥需要这样做呢?

一个线程抛出异常之后,只会在控制台打印堆栈信息,即使有日志记录,因为程序捕获不到异常,只会在控制台打出,并不是在日志记录中出现。

所以,除非在线程抛出异常的时候,你刚好在观察控制台输出的日子,看到了堆栈信息,否则,很难找到线程是哪里抛出了异常。

所以上面我们说到的捕获线程内异常,就有用了,正常情况下,我们捕获不到线程内的异常,但是我们可以通过 UncaughtExceptionHandler 来进行捕获异常。并在在Handler中打印出错误日志,方便定位排查问题。


UncaughtExceptionHandler 接口

先看下 Thread类中的UncaughtExceptionHandler接口


示例

两个线程,一个线程一直运行 ,另外一个线程有异常(一个数组下标越界异常,一个OOM异常 )

这里用OOM来演示

JVM参数设置: -Xms10m -Xmx10m

package com.artisan.test;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public class CaughtThreadExceptionDemo {public static void main(String[] args) {List list = Arrays.asList(1, 2, 3);// 模拟线程一 抛出异常 被终止Thread t = new Thread(() -> {try {Thread.sleep(2_000);
//                list.get(99);List list2 = new ArrayList();for (int i = 0; i < Integer.MAX_VALUE; i++) {list2.add(i + "biubiubiubiubiubiubiubiubiubiubiubiu");}} catch (InterruptedException e) { // 这个地方不要捕获 ArrayIndexOutOfBoundsException ,否则setUncaughtExceptionHandler无法捕获到该异常System.out.println(Thread.currentThread().getName() + " some error happened....");e.printStackTrace();}}, "TEST_THREAD_1");// 线程启动之前setUncaughtExceptionHandlert.setUncaughtExceptionHandler((thread, e) -> {System.out.println(" UncaughtExceptionHandler handle...." + e);System.out.println(" UncaughtExceptionHandler handle...." + thread.getName());});t.start();// 线程二 一直运行new Thread(() -> {while (true) {try {Thread.sleep(10_000);System.out.println(Thread.currentThread().getName() + " working...");} catch (InterruptedException e) {e.printStackTrace();}}}, "TEST_THREAD_2").start();}
}

输出

注意事项

  1. 要处理的异常,不要被run方法中的catch捕获(如果有catch的话)
  2. setUncaughtExceptionHandler 在 start之前调用

获取调用链

假设线程抛出如上异常,我们想记录下更多的信息到DB或者其他存储介质中,那如何打印出类似上面的信息呢?

答案就是: getStackTrace() ,然后把它的输出获取出来 。

示例如下:

package com.artisan.test;import java.util.Arrays;
import java.util.Optional;public class StackTraceDemo {public static void main(String[] args) {Test1 test1 = new Test1();test1.test1();}static class Test1 {public void test1() {new Test2().test2();}}static class Test2 {public void test2() {// Thread.currentThread().getStackTrace() 数组 转 List// List  stream ,然后过滤掉本地方法,最后遍历 输出Arrays.asList(Thread.currentThread().getStackTrace()).stream()// 过滤掉native方法.filter(element -> !element.isNativeMethod()).forEach(element -> Optional.of(element.getClassName() + ":" + element.getMethodName() + ":" + element.getLineNumber()).ifPresent(System.out::println));}}
}

输出如下:


使用线程池的场景: 获取线程运行时异常

戳这里

高并发编程-捕获线程运行时的异常 + 获取调用链相关推荐

  1. Java高并发编程:线程池

    这里首先介绍了java5中的并发的小工具包:java.util.concurrent.atomic,然后介绍了线程池的概念,对使用java5的方式创建不同形式的线程进行了演示,之后介绍了两个 对象:C ...

  2. Java高并发编程:线程范围内共享数据

    笔记摘要 所谓线程范围内共享数据,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行时又共享另外一份数据,API中为我们提供了一个操作线程范围内共享数据的类Threa ...

  3. Java高并发编程:线程锁技术

    目录 1 什么是线程锁 2 synchronized 1. 对象锁 2. 修饰对象方法 3. 类锁 4. 对象锁和类锁 5. 卖火车票示例 6. 生产一个消费一个示例 3 Lock 3.1 重入锁 R ...

  4. java线程高并发编程

    java线程详解及高并发编程庖丁解牛 线程概述: 祖宗: 说起java高并发编程,就不得不提起一位老先生Doug Lea,这位老先生可不得了,看看百度百科对他的评价,一点也不为过: 如果IT的历史,是 ...

  5. Java高并发编程详解系列-线程异常处理

    前面的博客中主要描述的关于线程的概念,通过源码分析了解线程的基本操作方式,但是如何在线程运行期间获取异常信息呢?这就要使用到一个Hook线程了 线程运行时的异常   在Thread类中,关于线程运行时 ...

  6. libevent c++高并发网络编程_高并发编程学习(2)——线程通信详解

    前序文章 高并发编程学习(1)--并发基础 - https://www.wmyskxz.com/2019/11/26/gao-bing-fa-bian-cheng-xue-xi-1-bing-fa-j ...

  7. 高并发编程学习(2)——线程通信详解

    前序文章 高并发编程学习(1)--并发基础 - https://www.wmyskxz.com/2019/11/26/gao-bing-fa-bian-cheng-xue-xi-1-bing-fa-j ...

  8. 高并发编程-使用wait和notifyAll进行线程间的通信3_多线程下的生产者消费者模型和notifyAll

    文章目录 概述 解决办法 概述 高并发编程-线程通信_使用wait和notify进行线程间的通信2_多生产者多消费者导致程序假死原因分析 中分析了假死的原因,这里我们来看下改如何解决在多线程下出现的这 ...

  9. 高并发编程-线程通信_使用wait和notify进行线程间的通信2_多生产者多消费者导致程序假死原因分析

    文章目录 概述 jstack或者可视化工具检测是否死锁(没有) 原因分析 概述 高并发编程-线程通信_使用wait和notify进行线程间的通信 - 遗留问题 我们看到了 应用卡住了 .... 怀疑是 ...

最新文章

  1. 脑机相连的狂想,马斯克实现了吗?智源观点:还很遥远
  2. 导入 sun.net.TelnetInputStream; 报错
  3. 高等数学、线性代数、概率论数理统计书籍推荐
  4. 因子和,因子数,1到n的因子和,1到n的因子数(积性函数)
  5. Could NOT find SDL_image (missing:SDL_IMAGE_LIBRARIES SDL_IMAGE_INCLUDE_DIRS)
  6. 栈和队列_入门oj题目练习:1用队列实现栈2用栈实现队列
  7. 浏览器清理缓存的几种方法
  8. 计算机网络专业术语大全
  9. 前端处理后端返回的二进制流文件
  10. c语言程序运行结果怎么看,c语言程序的运行结果.ppt
  11. 华为AR1220路由器配置GRE隧道
  12. 【kafka专栏】使用shell脚本快速安装kafka集群(含视频)
  13. Python request如何做接口测试
  14. 2020年12月特许金融分析师CFA考试难度分析!
  15. 俄罗斯品牌VOXTEL 520手机硬启动方法(恢复出厂)
  16. Webfrom --中国直辖市三区联动
  17. Jmeter请求参数MD5加密
  18. 推荐电影: 东北虎, 甘草披萨
  19. 爬取2019年央视新闻APP
  20. JavaScript 输出数据到文件中

热门文章

  1. html传递guid参数,C#中的Guid.ToString鲜为人知参数用法
  2. C++ open 打开文件(含打开模式一览表)
  3. c++   string类
  4. 129. Leetcode 202. 快乐数 (哈希表)
  5. 整数的二进制表达中有多少个1
  6. 深度学习~循环神经网络RNN, LSTM
  7. 李宏毅线性代数笔记 10: PageRank
  8. 机器学习笔记 RNN初探 LSTM
  9. tableau可视化数据分析60讲(十一)-排序和过滤器
  10. Matlab中常用希腊字母表查询