Java的线程异常处理器UncaughtExceptionHandler

简介

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;
				}
			}
		}
	}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值