UncaughtExceptionHandler 源码分析

x33g5p2x  于2022-03-29 转载在 其他  
字(1.6k)|赞(0)|评价(0)|浏览(221)

一 点睛

在没有向线程注入 UncaughtExceptionHandler 回调接口的情况下,线程若出现了异常又该如何处理,下面通过源码追踪下。

public UncaughtExceptionHandler getUncaughtExceptionHandler() {
    return uncaughtExceptionHandler != null ?
        uncaughtExceptionHandler : group;
}

getUncaughtExceptionHandler 首先会判断当前线程是否设置了 handler,如果有则执行自己的 uncaughtExceptionHandler 方法,否则就到所在的 ThreadGroup 中获取,ThreadGroup  同样也实现了 UncaughtExceptionHandler 接口。

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,则直接调用父 Group 的  uncaughtException 方法。
  • 如果设置了全局默认 UncaughtExceptionHandler,则调用 uncaughtException 方法。
  • 如果上面两者都没设置,则会直接将异常的堆栈信息定向到 System.err 中。

二 实战

1 代码

package concurrent;

import java.util.concurrent.TimeUnit;

public class EmptyExceptionhandler {
    public static void main(String[] args) {
        ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
        System.out.println(mainGroup.getName());
        System.out.println(mainGroup.getParent());
        System.out.println(mainGroup.getParent().getParent());

        Thread thread = new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(1/0);
        },"Test-Thread");
        thread.start();
    }
}

2 测试

main
java.lang.ThreadGroup[name=system,maxpri=10]
null
Exception in thread "Test-Thread" java.lang.ArithmeticException: / by zero
    at concurrent.EmptyExceptionhandler.lambda$main$0(EmptyExceptionhandler.java:18)
    at java.lang.Thread.run(Thread.java:748)

3 图解

相关文章