Java的线程异常处理器UncaughtExceptionHandler

来源:互联网 发布:mac梦幻西游怎么卸载 编辑:程序博客网 时间:2024/06/06 07:19

在Thread类中有个有个内部接口UncaughtExceptionHandler,这个接口定义了线程运行时遇到未被捕获的异常的规范,一般不设置这个处理器的时候,线程如果遇到未被捕获的异常则会终止。设置这个处理器之后可以用于统一记录线程抛出的异常。

在Thread中有2个方法可以设置未捕获的异常处理:

  1. setDefaultUncaughtExceptionHandler()这个方法是静态,用于设置一个默认的全局异常处理器。
  2. setUncaughtExceptionHandler()这个方法是针对某个Thread对象的,可以用于对特定的线程进行未捕获的异常处理。

下面展示一个由于异常未被捕获而导致线程终止的例子:

/** * 线程由于异常未被捕获导致线程终止的例子 * @author RJH * 2017年11月21日 */public class TerminatedByUncaughtExceptionDemo {    public static void main(String[] args) {        Thread thread = new Thread(new Runnable() {            private int  i = 0;            @Override            public void run() {                while (true) {//死循环自增                    ++i;                    if (i > 2) {//大于2则抛出异常                        throw new RuntimeException("i is bigger than 2");                    }                }            }        });        thread.start();        //线程如果依然存活,则死循环        while (thread.isAlive()) {        }        //此时线程已终止,状态为TERMINATED        System.out.println(thread.getState());    }}

运行结果:

Exception in thread "Thread-0" java.lang.RuntimeException: i is bigger than 2    at com.rjh.thread.TerminatedByUncaughtExceptionDemo$1.run(TerminatedByUncaughtExceptionDemo.java:14)    at java.lang.Thread.run(Thread.java:745)TERMINATED

这里需要注意Thread和Runnable中只能抛出RuntimeException,这是由于Runnable中的run()方法定义所导致的。

下面就用这个异常处理器实现一个模拟全局的日志记录的例子,这个例子的注释都比较齐全,大家只要看着注释基本就能明白了:

import java.lang.Thread.UncaughtExceptionHandler;/** * 线程异常处理器的例子 * @author RJH  * @date 2017年11月21日 下午9:32:13 */public class UncaughtExceptionHandlerDemo {    public static void main(String[] args) {        //设置一个全局的异常处理器        Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {            @Override            public void uncaughtException(Thread t, Throwable e) {                //用系统异常输出流输出类似日志的信息(其实就是模拟日志),格式是 时间戳 线程名称 异常名称 异常信息                //这里在实际开发的时候要记得把异常堆栈也打印出来,这样便于排查问题                System.err.println(String.format("%d %s %s",System.currentTimeMillis(),t.getName(),e.toString()));            }        });        //通过for循环启动多个线程        for(int i=0;i<5;i++){            Thread t=new ExceptionThread();            t.start();        }    }    /**     * 抛出异常的线程,一般情况下最好还是不要继承Thread,建议是实现Runnable接口     * @author RJH      * @date 2017年11月21日 下午9:36:46     */    private static class ExceptionThread extends Thread{        private int i=10;        @Override        public void run(){            while(10/i>0){//i不断自减,最后会抛出一个ArithmeticException                --i;            }        }    }}
阅读全文
0 0
原创粉丝点击