处理来自 Java ExecutorService 任务的异常 [英] Handling exceptions from Java ExecutorService tasks

查看:27
本文介绍了处理来自 Java ExecutorService 任务的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Java 的 ThreadPoolExecutor 类来运行大量具有固定线程数的重量级任务.每个任务都有很多地方可能会因为异常而失败.

I'm trying to use Java's ThreadPoolExecutor class to run a large number of heavy weight tasks with a fixed number of threads. Each of the tasks has many places during which it may fail due to exceptions.

我已经继承了 ThreadPoolExecutor 并且我已经覆盖了 afterExecute 方法,该方法应该提供在运行任务时遇到的任何未捕获的异常.但是,我似乎无法让它发挥作用.

I've subclassed ThreadPoolExecutor and I've overridden the afterExecute method which is supposed to provide any uncaught exceptions encountered while running a task. However, I can't seem to make it work.

例如:

public class ThreadPoolErrors extends ThreadPoolExecutor {
    public ThreadPoolErrors() {
        super(  1, // core threads
                1, // max threads
                1, // timeout
                TimeUnit.MINUTES, // timeout units
                new LinkedBlockingQueue<Runnable>() // work queue
        );
    }

    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        if(t != null) {
            System.out.println("Got an error: " + t);
        } else {
            System.out.println("Everything's fine--situation normal!");
        }
    }

    public static void main( String [] args) {
        ThreadPoolErrors threadPool = new ThreadPoolErrors();
        threadPool.submit( 
                new Runnable() {
                    public void run() {
                        throw new RuntimeException("Ouch! Got an error.");
                    }
                }
        );
        threadPool.shutdown();
    }
}

这个程序的输出是一切都很好——情况正常!"即使唯一提交给线程池的 Runnable 抛出异常.对这里发生的事情有任何线索吗?

The output from this program is "Everything's fine--situation normal!" even though the only Runnable submitted to the thread pool throws an exception. Any clue to what's going on here?

谢谢!

推荐答案

来自 文档:

注意:当动作包含在任务(例如 FutureTask)明确地或通过诸如提交,这些任务对象捕获并维护计算异常,以及所以他们不会引起突然终止和内部异常不会传递给这个方法.

Note: When actions are enclosed in tasks (such as FutureTask) either explicitly or via methods such as submit, these task objects catch and maintain computational exceptions, and so they do not cause abrupt termination, and the internal exceptions are not passed to this method.

当你提交一个 Runnable 时,它​​会被包裹在一个 Future 中.

When you submit a Runnable, it'll get wrapped in a Future.

你的 afterExecute 应该是这样的:

Your afterExecute should be something like this:

public final class ExtendedExecutor extends ThreadPoolExecutor {

    // ...

    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        if (t == null && r instanceof Future<?>) {
            try {
                Future<?> future = (Future<?>) r;
                if (future.isDone()) {
                    future.get();
                }
            } catch (CancellationException ce) {
                t = ce;
            } catch (ExecutionException ee) {
                t = ee.getCause();
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt();
            }
        }
        if (t != null) {
            System.out.println(t);
        }
    }
}

这篇关于处理来自 Java ExecutorService 任务的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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