【Kill Thread Part.1-7】线程异常处理知多少?

发布时间:2022-06-21 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了【Kill Thread Part.1-7】线程异常处理知多少?脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

【Kill Thread Part.1-7】线程异常处理知多少?

  • Java异常体系图
  • 实际工作中,如何全局处理异常?为什么要全局处理?不处理行不行?

一、线程未捕获异常UncaughtException应该如何处理?

1、为什么需要UncaughtExceptionHandler?

①主线程可以轻松发现异常,子线程却不行

测试代码

/**
 * 描述:  单线程,抛出,处理,有异常堆栈
 * 多线程,子线程如果发生异常,会有什么不同
 */
public class ExceptionInChildThread implements Runnable{
    @override
    public void run() {
        throw new RuntimeException();
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new ExceptionInChildThread());
        thread.start();
        for (int i = 0; i < 1000; i++) {
            System.out.PRintln(i);
        }
    }
}

【Kill Thread Part.1-7】线程异常处理知多少?

子线程运行抛出了异常,但是对于我们主线程而言,运行没有收到丝毫的影响。

②子线程异常无法用传统方法捕获

测试代码

/**
 * 描述:
 * 1.不加 try catch 抛出4个异常,都带线程名字
 * 2.加了try catch,期望捕获到第一个线程的异常,线程234不应该运行,希望看到打印出Caught Exception
 * 3.执行时发现,根本没有Caught Exception,线程234依然运行并且抛出异常
 * 说明线程的异常 不能用传统的方法捕获
 */
public class CantCatchDirectly implements Runnable{
    @Override
    public void run() {
        throw new RuntimeException();
    }

    public static void main(String[] args) throws InterruptedException {
        try {
            new Thread(new CantCatchDirectly(),"MyThread-1").start();
            Thread.sleep(300);

            new Thread(new CantCatchDirectly(),"MyThread-2").start();
            Thread.sleep(300);

            new Thread(new CantCatchDirectly(),"MyThread-3").start();
            Thread.sleep(300);

            new Thread(new CantCatchDirectly(),"MyThread-4").start();
        } catch (InterruptedException e) {
            System.out.println("Caught Exception");
        }
    }
}

【Kill Thread Part.1-7】线程异常处理知多少?

原因是try/catch只能捕获对应线程类的异常。

③不能直接捕获的后果、提高健壮性

如果不能捕获异常,子线程挂掉了,主线程还在运行,那么业务没人处理了,内部发生了错误。

二、两种解决方案

1、手动在每个run方法里进行try/catch(不推荐)

【Kill Thread Part.1-7】线程异常处理知多少?

2、利用UncaughtExceptionHandler(推荐)

  • UncaughtExceptionHandler接口
  • void uncaughtException(Thread t, Throwable e)

异常处理器的调用策略

【Kill Thread Part.1-7】线程异常处理知多少?

三、自己实现异常处理器

  • 给程序统一的设置
  • 给每个线程单独设置
  • 给线程池设置

1、自定义的异常处理器

import java.util.LOGging.Level;
import java.util.logging.Logger;

/**
 * 描述:自己的未处理异常处理器
 */
public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
    private String name;

    public MyUncaughtExceptionHandler(String  name) {
        this.name = name;
    }
    @Override
    public void uncaughtException(Thread t, Throwable e) {
        Logger logger = Logger.getAnonymousLogger();
        logger.log(Level.WARNING, t.getName() + "线程异常!终止了!", e);
        System.out.println(name + "捕获了异常" + t.getName() + "异常" + e);
    }

}

2、使用自定义的异常处理器

/**
 * 描述: 使用上面自己写的handler
 */
public class UseOwnUncaughtExceptionHandler implements Runnable{
    public static void main(String[] args) throws InterruptedException {
        Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler("捕获器1"));

        new Thread(new UseOwnUncaughtExceptionHandler(), "MyThread-1").start();
        Thread.sleep(300);
        new Thread(new UseOwnUncaughtExceptionHandler(), "MyThread-2").start();
        Thread.sleep(300);
        new Thread(new UseOwnUncaughtExceptionHandler(), "MyThread-3").start();
        Thread.sleep(300);
        new Thread(new UseOwnUncaughtExceptionHandler(), "MyThread-4").start();
    }


    @Override
    public void run() {
        throw new RuntimeException();
    }
}

四、常见面试问题

1、Java异常体系

2、如何全局处理异常?为什么要全局处理?不处理行不行?

3、run方法是否可以抛出异常?如果抛出异常,线程的状态会怎么样?

  • run方法不能上抛异常,只能是进行try/catch处理。
  • 线程会终止运行,打印出堆栈。

4、线程中如何处理某个未处理的异常?

脚本宝典总结

以上是脚本宝典为你收集整理的【Kill Thread Part.1-7】线程异常处理知多少?全部内容,希望文章能够帮你解决【Kill Thread Part.1-7】线程异常处理知多少?所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。