我有 5000 个类似的 Callable 任务要在 Executors.newFixedThreadPool(8) 创建的 ExecutorService 的 8 个线程中执行。每个任务都进入数据库以检索大量数据以进行处理。
一切正常 99% 的时间,但有时我在日志文件中看到非常奇怪的执行日志消息,当 DB 很慢或卡住(不要问为什么)并且 8 个当前正在运行的任务在所有 8 个线程中都停止并且尚未完成, ExecutorService 开始提交更多的任务来一一执行!
所以日志显示,在某些时候 ExecutorService 发疯了,开始调用 Callable 的 call() 方法,等待队列中越来越多的任务没有等待前面的任务完成。越来越多的任务向 DB 发送请求,最终导致 DB 崩溃,Java 堆内存耗尽。
看起来 ExecutorService 内部发生了一些奇怪的事情,或者我对这种情况的理解是错误的。有没有人见过这样的东西?
我的大脑堆栈溢出了
ps 是来自 Java API 的引用:
Executors.newFixedThreadPool(int nThreads)
创建一个线程池,该线程池重用在共享无界队列上运行的固定数量的线程。在任何时候,最多 nThreads 个线程将是活动的处理任务。如果在所有线程都处于活动状态时提交了其他任务,它们将在队列中等待,直到有线程可用。如果任何线程在关闭之前的执行过程中由于失败而终止,如果需要执行后续任务,新的线程将取代它。
如果我的任务导致线程死亡并且 ExecutorService 创建更多线程并向它们提交新的 8 个任务并且它们死亡并且 ExecutorService 创建更多线程并提交更多 8 个任务,这是否真的会发生?
pss:Callable 的 call() 内部的整个操作都被 try catch 包围,因此如果我的操作内部发生任何异常,则会捕获并记录该异常。这一切都没有发生。该调用被调用并且永远不会返回,而下一个任务被一个一个调用并且永远不会返回并且永远不会完成并且永远不会抛出任何异常。
我怀疑我的任务导致线程池中的线程死亡。怎么可能模仿?