多线程异常捕获与处理

2018-05-17  本文已影响0人  qingshuiting

线程与异常

每一个Java应用程序都是一个进程,在进程中会启动多个线程来执行各类任务。因为Java线程的本质,所以当在一个Java的线程中抛出异常的时候,需要在当前线程中catch并处理。如果当前线程没有catch住这个异常,那么这个异常就会被抛出,并导致这个线程运行终止。因此对于Java的线程异常处理只能由当前线程来处理,其他线程是无法感知的。

处理方式

  1. 基于内部try,catch的方式
public void run(){
try{

}catch(Throwable e){
         backgroundException = e;
}
}

在主线程,或者其他线程判断对应的backgroundException是否为null,如果不为null表示上次线程执行过程中出现了异常,然后执行异常处理逻辑。

  1. 基于异常处理器的方法

在Java中有一个异常处理器uncaughtExceptionHandler的接口,并且每一个线性对象Thread都有一个属性:uncaughtExceptionHandler。如果一个线程内部产生了异常,并且没有try,catch来处理,最终会被uncaughtExceptionHandler这个对象捕获。如果uncaughtExceptionHandler这个对象为null的话,这个异常就无法被捕获。

示例:

实现UncaughtExceptionHandler接口


public class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {
           @Override
           publicvoid uncaughtException(Thread t, Throwable e) {

                     System.out.println("捕获到异常:"+e);

                     //TODO处理异常的逻辑

           }
}

设置线程对象的uncaughtExceptionHandler

Thread thread = new Thread();
MyUncaughtExceptionHandler exceptionHandler = new  MyUncaughtExceptionHandler();
thread.setUncaughtExceptionHandler(exceptionHandler);

线程池中使用的问题(正在仔细研究线程池的底层实现)

在实践中我们常常使用线程池来管理线程任务。通常提交任务的方式有两种(除了定时任务外)execute,submit(有future返回值)。

如果希望线程在执行出现异常的时候,使用方法2的方式来捕获异常,就需要实现自己的ThreadFactory,为每一个Thread对象都设置异常处理器uncaughtExceptionHandler。但是这种方法只有在以execute提交任务的时候才有效。

对于submit提交的任务,会有一个future返回值,可以通过future的get方法获得最终线程的执行结果或者异常。

上一篇下一篇

猜你喜欢

热点阅读