问题描述
在发现 FutureTask
在 Java 1.6(和来自 Eclipse)上的 Executors.newCachedThreadPool()
中运行后吞下了 Runnable.run()
方法,我试图想出一种方法来捕获这些,而无需将 throw/catch 添加到我所有的 Runnable
实现中.
After finding that FutureTask
running in a Executors.newCachedThreadPool()
on Java 1.6 (and from Eclipse) swallows exceptions in the Runnable.run()
method, I've tried to come up with a way to catch these without adding throw/catch to all my Runnable
implementations.
API 建议重写 FutureTask.setException()
应该有助于此:
The API suggests that overriding FutureTask.setException()
should help in this:
导致这个未来报告一个 ExecutionException 以给定的 throwable 作为其原因,除非这个 Future 已经被设置或被取消.该方法在计算失败时由 run 方法在内部调用.
但是这个方法似乎没有被调用(与调试器一起运行显示异常被 FutureTask
捕获,但是 setException
没有被调用).我编写了以下程序来重现我的问题:
However this method doesn't seem to be called (running with the debugger shows the exception is caught by FutureTask
, but setException
isn't called). I've written the following program to reproduce my problem:
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);
}
}
我的主要问题是:如何捕获 FutureTask 中抛出的异常?为什么 setException
没有被调用?
My main question is: How can I catch Exceptions thrown in a FutureTask? Why doesn't setException
get called?
我也想知道为什么FutureTask
没有使用Thread.UncaughtExceptionHandler
机制,有什么原因吗?
Also I would like to know why the Thread.UncaughtExceptionHandler
mechanism isn't used by FutureTask
, is there any reason for this?
推荐答案
setException
可能不是为了覆盖而设计的,而是为了让您在需要时将结果设置为异常而提供的.您想要做的是覆盖 done()
方法并尝试获取结果:
setException
probably isn't made for overriding, but is provided to let you set the result to an exception, should the need arise. What you want to do is override the done()
method and try to get the result:
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);
}
}
}
这篇关于如何在 FutureTask 中捕获异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!