java - 处理 Java ExecutorService 任务的异常

标签 java multithreading exception executorservice threadpoolexecutor

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

我对 ThreadPoolExecutor 进行了子类化,并重写了 afterExecute 方法,该方法应该提供运行任务时遇到的任何未捕获的异常。但是,我似乎无法让它发挥作用。

例如:

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 抛出异常。对这里发生的事情有任何线索吗?

谢谢!

最佳答案

警告:需要注意的是,此解决方案将阻塞 future.get() 中的调用线程。

<小时/>

如果要处理任务抛出的异常,那么通常最好使用Callable而不是Runnable

Callable.call() 允许抛出已检查的异常,并且这些异常会传播回调用线程:

Callable task = ...
Future future = executor.submit(task);
// do something else in the meantime, and then...
try {
   future.get();
} catch (ExecutionException ex) {
   ex.getCause().printStackTrace();
}

如果Callable.call()抛出异常,该异常将被包装在ExecutionException中并由Future.get()抛出。

这可能比子类化 ThreadPoolExecutor 更可取。如果异常是可恢复的,它还使您有机会重新提交任务。

关于java - 处理 Java ExecutorService 任务的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57567043/

相关文章:

未检测到 css 文件时的 Python 异常以及如何检测 css 文件

java - 在我的加密字符串上附加新行

java - 如何为所有 Activity 建立一个共享线程?

java - 如何正确执行按位运算

Java 线程问题,处理程序消息数据被下一条消息覆盖

python - 运行开发服务器时,Bottle 框架的线程之一出现 OSError

exception - NotFoundException 的 HTTP 状态代码 500

c# - 在 try block 中尝试 catch - 异常应该调用相同的函数

java - 递归加法差异

java - 如何使用 Selenium Webdriver 和 Java 禁用 Firefox 中的不安全密码警告