之前的博客中介绍过Runnable类线程的异常处理,数据JAVA多线程的童鞋应该知道。Java中处理Thread和Runnable线程体系之外,还用著名的Executor和Callable线程体系。而且,后者在实际中更为常见。那么在Runnable中奏效的UncaughtExceptionHandler机制在Callable中时候仍然有效呢?我们用代码来验证一下。
import java.util.concurrent.*;
public class Demo {
private static final ExecutorService executorService = Executors.newSingleThreadExecutor();
public static void main(String[] args) {
Future<Integer> future = executorService.submit(new MyTask());
try {
System.out.println("myTask任务执行结果为" + future.get());
} catch (InterruptedException e) {
System.out.println("任务被中断!");
} catch (ExecutionException e) {
System.out.println("任务内部抛出未受检异常!");
} catch (CancellationException e){
System.out.println("任务被取消!");
}
executorService.shutdown();
}
private static final class MyTask implements Callable<Integer> {
@Override
public Integer call() throws Exception {
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("unchecked exception happened:");
System.out.println(t.getId());
System.out.println(t.getName());
e.printStackTrace(System.out);
}
});
int sum = 0;
for (int i = 4; i >= 0; i--) {
sum = sum + (12 / i);
}
return sum;
}
}
}
运行上面的程序发现,我们自定义的UncaughtExceptionHandler没有生效。相反,Executor框架的异常捕获机制倒是生效了。这说明Callable已经不再使用UncaughtExceptionHandler机制类处理非受检异常了,而是使用它自己特有的机制。这一特有的机制是什么呢?
在线程池中,线程池Executor会Catch住所有运行时异常,当使用Future.get()获取其结果时,才