Thi*_*ler 21 java concurrency executorservice futuretask
在发现在Java 1.6上FutureTask运行Executors.newCachedThreadPool()(以及从Eclipse中)吞下Runnable.run()方法中的异常后,我试图找到一种方法来捕获这些,而不向我的所有Runnable实现添加throw/catch .
API建议覆盖FutureTask.setException()应该有助于此:
导致此未来报告ExecutionException,并将给定的throwable作为其原因,除非已设置或已取消此Future.在计算失败时,run方法在内部调用此方法.
但是,似乎没有调用此方法(使用调试器运行显示异常被捕获FutureTask但setException未被调用).我写了以下程序来重现我的问题:
public class RunTest {
public static void main(String[] args) {
MyFutureTask t = new MyFutureTask(new Runnable() {
@Override
public void run() {
throw new RuntimeException("Unchecked exception");
}
});
ExecutorService service = Executors.newCachedThreadPool();
service.submit(t);
}
}
public class MyFutureTask extends FutureTask<Object> {
public MyFutureTask(Runnable r) {
super(r, null);
}
@Override
protected void setException(Throwable t) {
super.setException(t);
System.out.println("Exception: " + t);
}
}
Run Code Online (Sandbox Code Playgroud)
我的主要问题是:如何捕获FutureTask中引发的异常?为什么不setException打电话?
另外我想知道为什么Thread.UncaughtExceptionHandler机制没有使用FutureTask,有什么理由吗?
gus*_*afc 20
setException可能不是用于覆盖,但是如果需要,可以将结果设置为异常.你想要做的是覆盖done()方法并尝试获得结果:
public class MyFutureTask extends FutureTask<Object> {
public MyFutureTask(Runnable r) {
super(r, null);
}
@Override
protected void done() {
try {
if (!isCancelled()) get();
} catch (ExecutionException e) {
// Exception occurred, deal with it
System.out.println("Exception: " + e.getCause());
} catch (InterruptedException e) {
// Shouldn't happen, we're invoked when computation is finished
throw new AssertionError(e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Sou*_*ink 12
你试过用过UncaughtExceptionHandler吗?
UncaughtExceptionHandler接口.UncaughtExceptionHandlerfor pool线程,请ThreadFactory在Executor.newCachedThreadPool(ThreadFactory)调用中提供.setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)提交任务ExecutorService.execute,因为只有从提交的任务中抛出的异常execute才能使其成为未捕获的异常处理程序.对于随ExecutorService.submit任何抛出异常提交的任务,将被视为任务返回值的一部分.如果使用submit提交的任务以异常终止,则在调用时重新执行Future.get,包装在ExecutionException
小智 9
一个更好的解决方案: Java FutureTask完成检查
当您调用futureTask.get()以检索计算结果时,如果底层Runnable/ Callable抛出异常,它将抛出异常(ExecutionException).
ExecutionException.getCause()将返回Runnable/ Callable抛出的异常.
如果Runnable/ Callable被取消,它也会抛出不同的异常.
| 归档时间: |
|
| 查看次数: |
23525 次 |
| 最近记录: |