博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java线程中处理运行时异常(UncaughtExceptionHandler)
阅读量:3751 次
发布时间:2019-05-22

本文共 3125 字,大约阅读时间需要 10 分钟。

线程在执行单元中不允许抛出checked异常,而且线程运行在自己的上下文中,派生它的线程无法直接获得它运行中出现的异常信息。对此,Java为我们提供了UncaughtExceptionHandler接口,当线程在运行过程中出现异常时,会回调UncaughtExceptionHandler接口,从而得知是哪个线程在运行时出错。UncaughtExceptionHandler接口在Thread中定义。

Thread类中,关于处理运行时异常的API有四个:

  • public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh)
    为某个特定线程指定UncaughtExceptionHandler
  • public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh)
    设置全局的UncaughtExceptionHandler
  • public UncaughtExceptionHandler getUncaughtExceptionHandler()
    获取特定线程的UncaughtExceptionHandler
  • public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler()
    获取全局的UncaughtExceptionHandler

UncaughtExceptionHandler 简单使用

// 全局异常处理Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {	public void uncaughtException(Thread t, Throwable e) {		System.out.printf("Default , Thread name : %s , Exception : %s\n", t.getName(), e.getClass().getSimpleName());		e.printStackTrace();	}});Thread arithmetic = new Thread(() -> {	throw new ArithmeticException();}, "arithmetic");arithmetic.start();// ----------------------------------------------Thread nullPoint = new Thread(() -> {	throw new NullPointerException();}, "nullPoint");// 指定异常处理nullPoint.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {	public void uncaughtException(Thread t, Throwable e) {		System.out.printf("Assign , Thread name : %s , Exception : %s\n", t.getName(), e.getClass().getSimpleName());		e.printStackTrace();	}});nullPoint.start();

输出结果:

Default , Thread name : arithmetic , Exception : ArithmeticExceptionAssign , Thread name : nullPoint , Exception : NullPointerExceptionjava.lang.ArithmeticException	at com.p7.demo.UncaughtExceptionHandlerTest.lambda$0(UncaughtExceptionHandlerTest.java:24)	at java.lang.Thread.run(Thread.java:748)java.lang.NullPointerException	at com.p7.demo.UncaughtExceptionHandlerTest.lambda$1(UncaughtExceptionHandlerTest.java:32)	at java.lang.Thread.run(Thread.java:748)

UncaughtExceptionHandler 源码分析

/* The group of this thread,每创建一个Thread对象时,都会调用Thread的init方法,这个方法初始化了当前线程的线程组 */private ThreadGroup group;public UncaughtExceptionHandler getUncaughtExceptionHandler() {    return uncaughtExceptionHandler != null ?        uncaughtExceptionHandler : group;}

getUncaughtExceptionHandler方法首先判断当前线程是否设置了handler,如果有则使用自己的uncaughtException方法,否则就在所属的ThreadGroup中获取,ThreadGroup实现了UncaughtExceptionHandler

private final ThreadGroup parent;public void uncaughtException(Thread t, Throwable e) {    if (parent != null) {        parent.uncaughtException(t, e);    } else {        Thread.UncaughtExceptionHandler ueh =            Thread.getDefaultUncaughtExceptionHandler();        if (ueh != null) {            ueh.uncaughtException(t, e);        } else if (!(e instanceof ThreadDeath)) {            System.err.print("Exception in thread \""                             + t.getName() + "\" ");            e.printStackTrace(System.err);        }    }}

ThreadGroup如果有父ThreadGroup,则直接调用父GroupuncaughtException;如果设置了全局默认的UncaughtExceptionHandler,调用全局的uncaughtException;如果没有父ThreadGroup且没有全局默认的UncaughtExceptionHandler,直接将异常的堆栈信息定向到System.err中。

转载地址:http://qvcsn.baihongyu.com/

你可能感兴趣的文章
牛客编程题(九)
查看>>
过滤流
查看>>
3.输入整型数组和排序标识,对其元素按照升序或降序进行排序
查看>>
13.找到字符串的最长无重复字符串字串
查看>>
java常用垃圾回收器G1和CMS有什么区别
查看>>
BIO、NIO,AIO的区别
查看>>
linux压缩与解压
查看>>
数据结构基础(一)
查看>>
Linux反弹shell姿势总结
查看>>
CVE-2018-2894 WebLogic远程上传漏洞复现
查看>>
Nginx解析漏洞复现
查看>>
GhostScript沙箱绕过(命令执行漏洞)CVE-2018-16509
查看>>
通过图片获取地理位置
查看>>
PHP提权姿势
查看>>
Linux VI VIM编辑器
查看>>
Linux 进程管理
查看>>
Vulmap的使用
查看>>
SPSS Modeler工具笔记
查看>>
逻辑题分享
查看>>
后端开发中常用的语言
查看>>