0

我们正在使用通过 ExecutorService#newCachedThreadPool 创建的 CachedThreadPool。(Java 1.6)。我们在代码的其他地方遇到错误:“无法创建新的本机线程”,我们已将其诊断为内存不足问题。当这个问题发生时,我们调用提交的代码块(我们使用提交,而不是执行)会变慢。我们怀疑 ThreadPool 在尝试创建新线程来处理任务时遇到了相同的问题“无法创建新的本机线程”,但我们不能确定。

有没有办法从 ExecutorService 内部捕获异常?100% 清楚,我不是在谈论赋予 ExecutorService 的任务,而是来自 ExecutorService 本身。

4

2 回答 2

3

Executors.newCachedThreadPool创建一个ThreadPoolExecutor具有无限的最大线程池大小(注意构造函数的第二个参数)ThreadPoolExecutor

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

这意味着如果您提交任务的速度超过消耗率,将为每个新任务创建新线程,最终它将达到系统限制并抛出“无法创建新的本机线程”异常。

要解决此问题,您需要更改以下配置ThreadPoolExecutor

  1. 使用合理的 ThreadPoolExecutor。
  2. ThreadPoolExecutor用尽时选择适当的拒绝策略。

例如:

ExecutorService executorService = new ThreadPoolExecutor(5,200,
                          60L, TimeUnit.SECONDS,
                          new ArrayBlockingQueue(1000),
                          Executors.defaultThreadFactory(),
                          new ThreadPoolExecutor.CallerRunsPolicy());

请阅读JavaDocs了解配置细节。

于 2013-04-11T01:51:56.207 回答
0

您可以使用实现 Runnable 的自定义类,其中包含一组异常,如下所示:

public class MyRunnable implements Runnable {
    private List<Exception> exceptions;

    ...

    public void addException(Exception e) { ... }
    public void getExceptions(){ ... }
}

在所有可运行对象完成执行后,您可以检查它们内部的异常并抛出另一个异常作为响应。

于 2013-08-23T21:51:11.820 回答