听起来您有两个不同的问题:
1)您过度使用工作队列。你不能一直往队列里塞新任务,而不考虑任务执行者的消耗率。您需要找出一些逻辑来了解何时阻止新添加到工作队列中。
2)任务线程中任何未捕获的异常都可以完全杀死线程。发生这种情况时,ExecutorService 会启动一个新线程来替换它。但这并不意味着您可以忽略导致线程首先死亡的任何问题!找到那些未捕获的异常并捕获它们!
这只是一种预感(因为您的帖子中没有足够的信息来了解其他情况),但我不认为您的问题是任务执行者停止处理任务。我的猜测是它处理任务的速度不如您创建它们的速度快。(而且您的任务有时会过早终止这一事实可能与问题无关。)
至少,这是我使用线程池和任务执行器的经验。
好的,根据您的评论,这是另一种听起来可行的可能性(一切都会顺利运行几个小时,直到突然停止)......
您的任务线程之间可能会出现罕见的死锁。大多数时候,你很幸运,僵局并没有表现出来。但偶尔,您的两个或多个任务线程会进入等待释放另一个线程持有的锁的状态。此时,无法进行更多任务处理,并且您的工作队列将堆积起来,直到您收到 OutOfMemoryError。
这是我诊断该问题的方法:
消除任务线程之间的所有共享状态。首先,这可能需要每个任务线程制作它所需的所有共享数据结构的防御性副本。一旦你这样做了,就应该完全不可能遇到死锁。
此时,逐渐重新引入共享数据结构,一次一个(具有适当的同步)。在每次微小修改后重新运行您的应用程序以测试死锁。当您再次遇到这种崩溃情况时,请仔细查看共享资源的访问模式并确定您是否真的需要共享它。
就我而言,每当我编写处理带有线程池和执行器的并行任务的代码时,我总是试图消除这些任务之间的所有共享状态。就应用程序而言,它们也可能是完全自主的应用程序。寻找死锁是一种拖累,根据我的经验,消除死锁的最佳方法是让每个线程拥有自己的本地状态,而不是与其他任务线程共享任何状态。
祝你好运!