java - 如何在 FutureTask 中捕获异常

标签 java concurrency executorservice futuretask

在发现 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/

相关文章:

扫描 AWS S3 时,Python 线程池比 Go 例程更快?

java - ExecutorService 在超时后中断任务

java - Swingworker队列和单用

java - T extends SomeClass 的意义是什么?

Java:如何找出字体的大写高度和 x 高度?

java - 具有私有(private)构造函数的类中静态变量的初始化

java - "rename"文件项

java - 多线程 Java 应用程序中的问题 - 同步方法未按预期工作

multithreading - 为什么本地创建的结构不能发送到另一个线程?

java - ExecutorService控制线程池