java todo error_Java全局异常处理(TODO)

##spring mvc全局异常处理

##原生servlet全局异常处理

##非web java程序全局异常处理.

##对未捕获异常进行记录

###使用Thread产生的异常. 使用Thread的方法有两种:

继承Thread重载run方法

创建Runnable传给Thread

这两种方式,执行代码都是放在run方法里的.如果run方法抛出了RuntimeException,我们怎么才能知道呢. Thread有一个静态方法setDefaultUncaughtExceptionHandler和一个普通方法setUncaughtExceptionHandler,是用来处理这种异常的. 默认的handler在遇到异常时,会把异常堆栈打印到System.err.是的,就像我们通常所见的那样,红字打印到控制台. 如果想要把这些异常也用logger工具记录的话,就要设置我们自定义的UncaughtExceptionHandler了.

###使用线程池产生的异常 提到线程池,也就是1.5之后新增的并发库了.常用的实现类就是ThreadPoolExecutor了. ThreadPoolExecutor有submit方法和execute方法,这两种方法都是用来提交执行任务的,他们的区别在于一种返回Future而另一种返回空.

对于Future的情况,执行任务期间产生的异常都被重新包装为ExecutionException,只有任务执行完成调用Future#get方法的时候,这个异常才会被抛出.

对于execute方法.执行任务期间产生的异常会被记录,然后在执行ThreadPoolExecutor#afterExecute方法时作为参数传入.由于该方法默认为空,所以这种情况下异常就像被吃掉一样莫名其妙消失了.

如何对上面两种情况产生的异常进行记录? 第二种比较简单,重载afterExecute进行记录即可.而第一种情况则需要一个恰当的时间点:在任务执行完成之后,调用get方法,然后捕获并记录异常.刚刚提到的afterExecute方法正好符合这个契机.所以这两种情况都可以放在afterExecute中进行处理. 处理代码类似于这样(参考链接):

protected void afterExecute(Runnable r, Throwable t) {

super.afterExecute(r, t);

printException(r, t);

}

private static void printException(Runnable r, Throwable t) {

if (t == null && r instanceof Future>) {

try {

Future> future = (Future>) r;

if (future.isDone())

future.get();

} catch (CancellationException ce) {

t = ce;

} catch (ExecutionException ee) {

t = ee.getCause();

} catch (InterruptedException ie) {

Thread.currentThread().interrupt(); // ignore/reset

}

}

if (t != null)

log.error(t.getMessage(), t);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值