在发现 FutureTask
在 Java 1.6(以及来自 Eclipse)的 Executors.newCachedThreadPool()
中运行后,会在 Runnable.run()
方法,我试图想出一种方法来捕获这些,而无需将 throw/catch 添加到我所有的 Runnable
实现中。
API 建议重写 FutureTask.setException()
应该有助于:
Causes this future to report an ExecutionException with the given throwable as its cause, unless this Future has already been set or has been cancelled. This method is invoked internally by the run method upon failure of the computation.
然而,这个方法似乎没有被调用(使用调试器运行显示异常被 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);
}
}
我的主要问题是:如何捕获 FutureTask 中抛出的异常?为什么不调用 setException
?
另外我想知道FutureTask
为什么不使用Thread.UncaughtExceptionHandler
机制,有什么原因吗?
最佳答案
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);
}
}
}
关于java - 如何在 FutureTask 中捕获异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3555302/