20210601 线程池中的异常处理

线程池异常处理

1,Runnable接口的run方法的完整签名,没有标识throws语句,所以方法是不会抛出checked异常的。至于RuntimeException这样的unchecked异常,由于新线程由JVM进行调度执行,如果发生了异常,也不会通知到父线程。

即:子线程中发生了异常,如果没有任何类来接手处理的话,是会直接退出的,虚拟机直接杀死线程,而不会记录任何日志。所以,如果什么都不做的话,是会出现子线程任务既没执行成功,也没有任何日志提示的“诡异”现象的。

java线程中,如果抛出未被捕获的异常,会导致线程终止。

2,一旦一个线程抛出了非受检异常,JVM就会把它杀死,然后把捕获到的非受检异常传递给UncaughtExceptionHandler类对象类处理.

3,当一个线程由于发生了非受检异常而终止时,JVM会使用Thread.gerUncaughtExceptionHandler()方法查看该线程上的UncaughtExceptionHandler,并调用他的uncaughtException()方法。

4,在使用线程池的时候,自己设置异常处理,获取线程的异常信息。

在父线程中启动了子线程,捕获子线程中的异常,从而进行相应的处理。

方法一,在子线程的执行方法中,将整个任务try-catch起来,捕获里面的异常。

方法二: 每一个任务都加一个try-catch 实在是太麻烦了,而且代码也不好看,那么这样想的话,可以用UncaughtExceptionHandler 这个类。

UncaughtExceptionHandler 是Thread类一个内部类,也是一个函数式接口。内部的uncaughtException是一个处理线程内发生的异常的方法,参数为线程对象t和异常对象e。

如果我们不想在每个线程的任务里面都加try-catch的话,可以自己实现的一个线程池,重写它的线程工厂方法,在创建线程的时候,都赋予UncaughtExceptionHandler处理器对象。

    private static ThreadFactory threadFactory = new ThreadFactoryBuilder()
            .setNameFormat("thread-pool-%d")
            .setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
                @Override
                public void uncaughtException(Thread t, Throwable e) {
                    //子线程抛出异常
                    log.info("子线程执行异常,线程名:{},异常信息:{}", t.getName(), e.getMessage());
                }
            })
            .build();

 

setDefaultUncaughtExceptionHandler的原理

Thread类里面dispatchUncaughtException(Throwable e) 这个方法,调用了 getUncaughtExceptionHandler().uncaughtException(this, e); 获取到了我们设置的UncaughtExceptionHandler,并把线程对象和异常对象都作为参数传进去了。这个方法,只能被JVM调用,将未捕获异常分派给该方法所在的处理程序调用的节点,就是当Thread对象抛出了未被捕获的异常的时候。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值