从(ExecutorService)CachedThreadPool捕获异常

时间:2013-04-10 23:21:45

标签: java executorservice

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

有没有办法从ExecutorService中捕获异常? 为了100%明确,我不是在谈论给予ExecutorService的任务,而是来自ExecutorService本身。

2 个答案:

答案 0 :(得分:2)

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用尽时选择正确的拒绝政策。
  3. 例如:

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

    请阅读JavaDocs了解配置详情。

答案 1 :(得分:0)

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

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

    ...

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

在所有runnables完成执行后,您可以检查其中的异常,并在响应中抛出另一个异常。