本文介绍了如何在 FutureTask 中捕获异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在发现 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 中捕获异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-30 04:57