我们正在使用通过ExecutorService#newCachedThreadPool创建的CachedThreadPool。 (Java 1.6)。我们在代码中的其他地方遇到错误:“无法创建新的本机线程”,我们已将其诊断为内存不足问题。当这个问题发生时,我们调用submit(我们使用submit,而不是execute)的代码块会变慢。我们怀疑ThreadPool在尝试创建新线程来处理任务时遇到了“无法创建新的本机线程”的相同问题,但我们无法确定。
有没有办法从ExecutorService中捕获异常? 为了100%明确,我不是在谈论给予ExecutorService的任务,而是来自ExecutorService本身。
答案 0 :(得分:2)
Executors.newCachedThreadPool
创建一个ThreadPoolExecutor
,其最大线程池大小不受限制(请注意ThreadPoolExecutor
构造函数的第二个参数):
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
这意味着如果您提交的任务比消耗速度快,则会为每个新任务创建新线程,最终它将达到系统限制并且抛出“无法创建新的本机线程”异常。
要解决此问题,您需要更改ThreadPoolExecutor
的配置:
ThreadPoolExecutor
用尽时选择正确的拒绝政策。例如:
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完成执行后,您可以检查其中的异常,并在响应中抛出另一个异常。