目录

Life in Flow

Embrace your dreams and unlock your full potential at every stage of life.

X

线程异常 UncaughtException

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

 UncaughtException 专门用于处理线程未捕获的异常。能检测出线程未捕获异常而终止的情况。
 主线程可以轻松的发现异常,子线程却不行,子线程即使抛出异常,主线程也不受影响。
 子线程异常无法用传统方法捕获。

示例:主线程可以轻松的发现异常,子线程却不行,子线程即使抛出异常,主线程也不受影响。

/**
 * 描述:     单线程,抛出,处理,有异常堆栈
 *           多线程,子线程发生异常,会有什么不同? 
 *           子线程抛出异常,主线程并不会中断
 *
 *  Exception in thread "Thread-0" java.lang.RuntimeException
 * 	at com.xdclass.couponapp.test.uncaughtexception.ExceptionInChildThread.run(ExceptionInChildThread.java:18)
 * 0
 * 1
 * 2
 */
public class ExceptionInChildThread implements Runnable {

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

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

示例:子线程异常无法用传统方法捕获。

package com.xdclass.couponapp.test.uncaughtexception;

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

    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 (RuntimeException e) {
            System.out.println("Caught Exception.");
        }

    }

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

利用 UncaughtExceptionHandler

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

示例:利用 UncaughtExceptionHandler (推荐)
 自定义全局异常处理器

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

/**
 * 描述:     自己的MyUncaughtExceptionHanlder
 */
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());
        System.out.println(name + " 捕获了异常 " + t.getName() + " 异常");
    }
}

  使用自定义 Handler 作为全局兜底异常处理

/**
 * 描述:     使用刚才自己写的UncaughtExceptionHandler
 */
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();
    }
}

console

三月 03, 2020 9:42:53 下午 com.xdclass.couponapp.test.uncaughtexception.MyUncaughtExceptionHandler uncaughtException
警告: 线程异常,终止啦MyThread-1
捕获器1 捕获了异常 MyThread-1 异常
三月 03, 2020 9:42:53 下午 com.xdclass.couponapp.test.uncaughtexception.MyUncaughtExceptionHandler uncaughtException
警告: 线程异常,终止啦MyThread-2
捕获器1 捕获了异常 MyThread-2 异常
三月 03, 2020 9:42:53 下午 com.xdclass.couponapp.test.uncaughtexception.MyUncaughtExceptionHandler uncaughtException
警告: 线程异常,终止啦MyThread-3
捕获器1 捕获了异常 MyThread-3 异常
三月 03, 2020 9:42:54 下午 com.xdclass.couponapp.test.uncaughtexception.MyUncaughtExceptionHandler uncaughtException
警告: 线程异常,终止啦MyThread-4
捕获器1 捕获了异常 MyThread-4 异常

未捕获异常 UncaughtException


作者:Soulboy