如何捕获FutureTask中的异常 [英] How to catch exceptions in FutureTask

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

问题描述

在Java 1.6(和Eclipse)上发现 FutureTask Executors.newCachedThreadPool()中运行swallows在 Runnable.run()方法中的异常,我试图想出一个方法来捕获这些没有添加throw / catch到我所有的 Runnable 实现。



API建议覆盖 FutureTask.setException()在此:


导致此未来以给定的throwable作为其原因报告ExecutionException,除非此Future已经设置或已经取消。在计算失败时,由run方法在内部调用此方法。


但是这个方法似乎没有被调用(运行调试器显示异常被 FutureTask ,但 setException 未调用)。我写了以下程序来重现我的问题:

  public class RunTest {
public static void main [] args){
MyFutureTask t = new MyFutureTask(new Runnable(){

@Override
public void run(){
throw new RuntimeException(Unchecked异常);

}
});

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 机制,是否有任何原因?

c> setException c>可能不是为了重写,而是提供来让你将结果设置为异常,需要出现。您想要做的是覆盖 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){
//异常发生,处理
System.out.println(Exception:+ e.getCause());
} catch(InterruptedException e){
//不应该发生,计算结束时调用
throw new AssertionError(e);
}
}
}


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.

The API suggests that overriding FutureTask.setException() should help in this:

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.

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);
    }
}

My main question is: How can I catch Exceptions thrown in a FutureTask? Why doesn't setException get called?

Also I would like to know why the Thread.UncaughtExceptionHandler mechanism isn't used by FutureTask, is there any reason for this?

解决方案

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆