gpt4 book ai didi

java - 什么会使单个任务执行器停止处理任务?

转载 作者:搜寻专家 更新时间:2023-10-31 08:18:38 24 4
gpt4 key购买 nike

我正在使用通过调用 Executors.newSingleThreadExecutor() 获得的 java.util.concurrent.ExecutorService。此 ExecutorService 有时会停止处理任务,即使它尚未关闭并继续接受新任务而不会抛出异常。最终,它建立了足够多的队列,以至于我的应用程序因 OutOfMemoryError 异常而关闭。

文档似乎表明这个单线程执行器应该通过在必要时启动一个新的工作线程来替换已经死亡的线程来幸免于任务处理错误。我错过了什么吗?

最佳答案

听起来您有两个不同的问题:

1) 你给工作队列提供了过多的信息。不能一直往队列里塞新任务,不管任务执行器的消耗率。您需要找出一些逻辑来了解何时阻止向工作队列添加新内容。

2) 任务线程中任何未捕获的异常都可以完全杀死线程。发生这种情况时,ExecutorService 会启动一个新线程来替换它。但这并不意味着您可以忽略导致线程首先死亡的任何问题!找到那些未捕获的异常并捕获它们!

这只是一种预感(因为您的帖子中没有足够的信息来了解其他信息),但我认为您的问题不是任务执行器停止处理任务。我的猜测是它处理任务的速度不如您创建任务的速度。 (而且您的任务有时会过早终止这一事实可能与问题无关。)

至少,这是我使用线程池和任务执行器的经验。


好的,根据您的评论,这是另一种听起来可行的可能性(一切都会平稳运行数小时,直到突然停止)...

您的任务线程之间可能会出现罕见的死锁。大多数时候,你很幸运,僵局不会出现。但有时,您的两个或多个任务线程会进入等待释放另一个线程持有的锁的状态。届时,将无法进行更多的任务处理,您的工作队列将堆积起来,直到出现 OutOfMemoryError。

以下是我诊断该问题的方法:

消除任务线程之间的所有共享状态。首先,这可能需要每个任务线程制作一份它需要的所有共享数据结构的防御性副本。一旦你这样做了,就应该完全不可能遇到死锁。

此时,逐渐重新引入共享数据结构,一次一个(适当同步)。在每次微小的修改后重新运行您的应用程序以测试死锁。当您再次遇到崩溃情况时,请仔细查看共享资源的访问模式并确定您是否真的需要共享它。

就我而言,每当我编写使用线程池和执行程序处理并行任务的代码时,我总是试图消除这些任务之间的ALL 共享状态。就应用程序而言,它们也可能是完全自治的应用程序。寻找死锁是一种拖累,根据我的经验,消除死锁的最佳方法是让每个线程拥有自己的本地状态,而不是与其他任务线程共享任何状态。

祝你好运!

关于java - 什么会使单个任务执行器停止处理任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/344788/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com