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()中的调用线程。


如果要处理任务抛出的异常,那么一般使用CallableRunnable好。

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/2248131/

相关文章:

java - 使用 jOOQ 查找即将到来的生日

java - 覆盖 hashCode() 和 equals() 方法

java - 创建一个线程来写入使用键盘输入的每个字符

delphi - TScriptControl - 类未注册

java - 复制包含另一个对象的父类(super class)的对象

java - 使用 JSONArray 和 JSONObject 进行 Foreach

java - spring 集成中的自定义并发 TcpOutboundGateway

c++ - 更快地处理 SendARP 函数

python - 如何在 Selenium Python 中设置 UnexpectedAlertBehaviour

c# - ASP.NET Core Web API 异常处理