线程基础核心 07 异常处理

admin / 开发 / ... / Reads: 2

1.案例

1.1.难以发现的子线程异常

简述:

1.在子线程child-exception-0中,抛出异常

2.主线程main依然正常执行,在实际项目中,会导致难以发现子线程的异常情况

package com.anan.thread.threadexception;

/**
 * 主线程main不能发现子线程异常
 */
public class NotFoundChildThreadException {

    public static void main(String[] args) {
        // 创建线程对象
        Runnable r1 = new MyRunnable();
        Thread t1 = new Thread(r1,"child-exception-0");
        t1.start();

        // 主线程循环打印输出,忽略子线程异常
        for (int i = 0; i < 5; i++) {
            System.out.println("主线程main输出:风景这边独好!当前索引【"
                    + i + "】");
        }

    }

}

/**
 * 实现Runnable,创建线程
 */
class MyRunnable implements Runnable{
    public void run() {
        System.out.println(Thread.currentThread().getName() +
                "准备抛出异常了...start");
        // 抛出异常
        throw  new RuntimeException("子线程抛出了异常.");
    }
}

10

1.2.不能捕获的子线程异常

简述:

1.创建3个子线程:thread-0、thread-1,thread-2

2.每个子线程都会抛出异常

3.在主线程main中,进行捕获处理。期望如果thread-0抛出了异常,那么thread-1/thread-2线程,不要创建执行

/**
 * 不能捕获的子线程异常
 */
public class NotCaughtChildException {

    public static void main(String[] args) {
        // 预期子线程会抛出异常,通过try{}catch(){}捕获处理
        try{
            // 创建子线程0
            Runnable r1 = new MyRunnable1();
            Thread t0 = new Thread(r1,"thread-0");
            t0.start();

            // 创建子线程1
            Thread t1 = new Thread(r1,"thread-1");
            t1.start();

            // 创建子线程2
            Thread t2 = new Thread(r1,"thread-2");
            t2.start();

        }catch (RuntimeException e){
            System.out.println("捕获到了异常.");
        }
    }
}

/**
 * 实现Runnable,创建线程
 */
class MyRunnable1 implements Runnable{
    public void run() {
        System.out.println(Thread.currentThread().getName() +
                "准备抛出异常了...start");
        // 抛出异常
        throw  new RuntimeException("子线程抛出了异常.");
    }
}

执行结果:

24

1.3.全局异常处理

简述:

1.在3.2.中,不能通过try{}catch(){}捕获子线程异常。因为try{}catch(){}只能捕获当前线程的异常

2.如果要对所有子线程,进行统一异常处理,需要一个全局异常处理器

3.全局异常处理器接口:Thread.UncaughtExceptionHandler

4.实现方式:

4.1.编写全局异常处理器,实现接口:Thread.UncaughtExceptionHandler

4.2.注册使用全局异常处理器

1.3.1.全局异常处理器

package com.anan.thread.threadexception;

/**
 * 自定义全局异常处理器类
 */
public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {

    public void uncaughtException(Thread t, Throwable e) {
        System.out.println(t.getName() + "发生了异常,异常消息:" + e.getMessage());
    }
}

1.3.2.注册使用全局异常处理器

package com.anan.thread.threadexception;

/**
 * 注册使用自定义全局异常处理器
 */
public class UseUncaughtExceptionHandler {

    public static void main(String[] args) {

        // 关键代码:设置全局异常处理器
        Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());

        // 创建子线程0
        Runnable r1 = new MyRunnable1();
        Thread t0 = new Thread(r1,"thread-0");
        t0.start();

        // 创建子线程1
        Thread t1 = new Thread(r1,"thread-1");
        t1.start();

        // 创建子线程2
        Thread t2 = new Thread(r1,"thread-2");
        t2.start();
    }
}

/**
 * 实现Runnable,创建线程
 */
class MyRunnable2 implements Runnable{
    public void run() {
        System.out.println(Thread.currentThread().getName() +
                "准备抛出异常了...start");
        // 抛出异常
        throw  new RuntimeException("子线程抛出了异常.");
    }
}

1.3.3.执行结果

33

关于作者

王硕,网名信平,十多年软件开发经验,业余架构师,精通Java/Python/Go等,喜欢研究技术,著有《PyQt 5 快速开发与实战》《Python 3.* 全栈开发》,多个业余开源项目托管在GitHub上,欢迎微博交流。

Comments

Make a comment

Author: admin

Publish at: ...

关于作者

王硕,网名信平,十多年软件开发经验,业余架构师,精通 C/Java/Python/Go 等,喜欢读书,音乐和宅在家里。
Email: xujieiata@163.com

www.ultrapower.com ultrapower 王硕的博客,专注于研究互联网产品和技术,提供中文精品教程。