简体   繁体   English

从(ExecutorService)CachedThreadPool捕获异常

[英]Catching Exceptions from (ExecutorService) CachedThreadPool

We are using a CachedThreadPool created via the ExecutorService#newCachedThreadPool. 我们正在使用通过ExecutorService#newCachedThreadPool创建的CachedThreadPool。 (Java 1.6). (Java 1.6)。 We are getting errors elsewhere in our code: "unable to create new native thread" which we've diagnosed as an out of memory problem. 我们在代码中的其他地方遇到错误:“无法创建新的本机线程”,我们已将其诊断为内存不足问题。 When this problem is happening, the block of code where we call submit (we use submit, not execute) slows down. 当这个问题发生时,我们调用submit(我们使用submit,而不是execute)的代码块会变慢。 We suspect that the ThreadPool is having the same issue "unable to create new native thread" when it is trying to create new threads to process the tasks, but we can't be sure. 我们怀疑ThreadPool在尝试创建新线程来处理任务时遇到了“无法创建新的本机线程”的相同问题,但我们无法确定。

Is there any way to catch exceptions from inside the ExecutorService? 有没有办法从ExecutorService中捕获异常? To be 100% clear, I'm not talking about the tasks given to the ExecutorService, but from the ExecutorService itself. 为了100%明确,我不是在谈论给予ExecutorService的任务,而是来自ExecutorService本身。

The Executors.newCachedThreadPool creates a ThreadPoolExecutor with a unlimited maximum thread pool size(note the second argument of ThreadPoolExecutor constructor): Executors.newCachedThreadPool创建一个ThreadPoolExecutor ,它具有无限的最大线程池大小(注意ThreadPoolExecutor构造函数的第二个参数):

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

That means if you are submitting tasks faster than the consuming rate, new threads will be created for each new tasks, eventually it will reach the system limit and the "unable to create new native thread" exception is thrown. 这意味着如果您提交的任务比消耗率更快,则将为每个新任务创建新线程,最终它将达到系统限制并且抛出“无法创建新的本机线程”异常。

To fix this, you need to change the configuration of ThreadPoolExecutor : 要解决此问题,您需要更改ThreadPoolExecutor的配置:

  1. Use a reasonable ThreadPoolExecutor. 使用合理的ThreadPoolExecutor。
  2. Choose a proper reject policy when the ThreadPoolExecutor is exhausted. ThreadPoolExecutor用尽时,选择适当的拒绝策略。

For example: 例如:

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

Please read the JavaDocs for configuration details. 请阅读JavaDocs以获取配置详细信息。

You could use a custom class that implements Runnable with a collection of excpetions inside, like this: 您可以使用一个自定义类来实现Runnable,其中包含一组excpetions,如下所示:

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

    ...

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

After all runnables finish their executions you could check for exceptions inside them and throw another exception in response. 在所有runnables完成执行后,您可以检查其中的异常,并在响应中抛出另一个异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM