为什么未捕获异常的处理逻辑看起来在发生异常的已终止线程中执行?
问题解答
核心原理
Java中UncaughtExceptionHandler的执行逻辑默认就是在抛出未捕获异常的线程本身的上下文中运行,不是在设置handler的线程(也就是你代码里的main线程)中运行的,你代码中handler里的注释in main thread是错误的,属于对该API的误解。
具体执行流程拆解
Thread-0的完整生命周期远不止执行你写的run()方法里的代码,未捕获异常的处理是线程终止前的内置流程,不存在“在已经执行完成的Thread-0中运行”的情况:
- 第一步:Thread-0执行完
run()方法里的throw new RuntimeException("purposeful!");,该异常没有被run()内部的try-catch捕获,属于线程未捕获异常 - 第二步:JVM检测到该异常后,会优先调用该线程预先设置的
UncaughtExceptionHandler的uncaughtException()方法,整个调用过程完全在Thread-0的执行上下文中完成,此时Thread-0还未终止 - 第三步:handler里的日志打印逻辑执行时,当前线程还是Thread-0,所以日志里打印的线程名自然是Thread-0
- 第四步:handler执行完成后,Thread-0才会正式退出终止
你也可以从日志时间验证这个逻辑:handler的日志打印时间是10:19:50,和Thread-0的业务日志时间完全一致,而main线程此时还处于TimeUnit.SECONDS.sleep(10)的阻塞状态,直到10秒后的10:20:00才会打印后续日志,显然不可能在阻塞状态下执行handler的逻辑。
内容的提问来源于stack exchange,提问作者HellishHeat
相关产品推荐
相关产品推荐

