线程未捕获的异常监控和处理--UncaughtExceptionHandler

UncaughtExceptionHandler接口

API概要

UncaughtExceptionHandler是在JDK1.5引入的一个接口,里面只有一个方法:
void uncaughtException(Thread t, Throwable e);
该方法中的第一个参数包含了异常终止的线程本身,第二个参数包含了导致线程终止的异常;
以下是官方对于此接口的文档说明

/**
     * Interface for handlers invoked when a {@code Thread} abruptly
     * terminates due to an uncaught exception.
     * <p>When a thread is about to terminate due to an uncaught exception
     * the Java Virtual Machine will query the thread for its
     * {@code UncaughtExceptionHandler} using
     * {@link #getUncaughtExceptionHandler} and will invoke the handler's
     * {@code uncaughtException} method, passing the thread and the
     * exception as arguments.
     * If a thread has not had its {@code UncaughtExceptionHandler}
     * explicitly set, then its {@code ThreadGroup} object acts as its
     * {@code UncaughtExceptionHandler}. If the {@code ThreadGroup} object
     * has no
     * special requirements for dealing with the exception, it can forward
     * the invocation to the {@linkplain #getDefaultUncaughtExceptionHandler
     * default uncaught exception handler}.
     *
     * @see #setDefaultUncaughtExceptionHandler
     * @see #setUncaughtExceptionHandler
     * @see ThreadGroup#uncaughtException
     * @since 1.5
     */
    @FunctionalInterface
    public interface UncaughtExceptionHandler {
        /**
         * Method invoked when the given thread terminates due to the
         * given uncaught exception.
         * <p>Any exception thrown by this method will be ignored by the
         * Java Virtual Machine.
         * @param t the thread
         * @param e the exception
         */
        void uncaughtException(Thread t, Throwable e);
    }

作用

1.Interface for handlers invoked when a Thread abruptly terminates due to an uncaught exception.

当一个线程由于未捕获的异常突然终止时会调用此接口

2.When a thread is about to terminate due to an uncaught exception
the Java Virtual Machine will query the thread for its * {@code UncaughtExceptionHandler}*
using * {@link #getUncaughtExceptionHandler}*
and will invoke the handler’s * {@code uncaughtException}* method,
passing the thread and the exception as arguments.

当一个线程由于一个未被捕获的异常终止时,虚拟机会通过 getUncaughtExceptionHandler() 方法去查询此线程是否设置了uncaughtExceptionHandler变量,如果 uncaughtExceptionHandler变量不为null,则调用此接口的uncaughtException方法处理这个未被捕获的异常.

这也说明了虚拟机对于线程未被处理异常的处理流程.
未被处理异常的处理流程

实例

	//定义 UncaughtExceptionHandler
    final Thread.UncaughtExceptionHandler uncaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            System.out.println("*********************************************");
            System.out.println("异常线程:" + t.getName());
            System.out.println("异常原因:" + e.getMessage());
            System.out.println("*********************************************");
        }
    };
    
	@Test
    public void ThreadUncaughtExceptionHandlerTest() throws InterruptedException, IOException {
        //创建线程
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //模拟耗时操作
                    doSomethings("Test Message");

                    //触发异常
                    int i= 10 / 0;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        //设置UncaughtExceptionHandler
        t.setUncaughtExceptionHandler(uncaughtExceptionHandler);

        //启动线程
        t.start();

        //等待子线程完成在退出
        t.join();
    }

执行结果:
执行结果

注意事项

当由线程池执行任务时在执行任务之前使用

Thread.currentThread().setUncaughtExceptionHandler(uncaughtExceptionHandler);

防止设置失效,因为使用线程池时任务的执行是由线程池分配线程的线程进行的.

posted @   清楚xc  阅读(139)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示