【发布时间】:2015-01-11 19:36:15
【问题描述】:
我将 Callable 任务(使用 submit())提交给 ExecutionService 的实现。偶尔我似乎遇到了死锁,但无法在发生死锁的位置或原因工作,所以我想为任务设置超时,我不清楚该怎么做?
我应该
- 在提交任务并设置超时时,在 ExecutionService 上使用 invokeAny() 而不是 submit()。我使用 submit() 一次提交许多任务,我可以像这样使用 invokeAny() 吗,我很谨慎,因为我不明白为什么没有需要超时的 submit() 方法。
- 在我的 ExecutorService 的构造函数中修改 keepAliveTime(但我认为这是在做其他事情
- 修改我的实际 Callable 实现,但如果它已死锁,则无法自行解除死锁。
选项 1 似乎是唯一可行的解决方案,但它是吗?
更多详情
我认为可能值得更详细地解释该过程的工作原理,以防它有助于解决问题。
可调用任务 P1 启动并在文件夹上工作,其中的所有文件和文件夹开始将歌曲分组,它在 ExecutorService ES1 中运行,并且只有一个 P1 实例提交给 ES1。
我们还有其他三个 Callable 类:P2、P3 和 P4 - 每一个都有自己关联的 Executor Service,ES2、ES3、Es4)。一旦 P1 创建了一个组,它就会向关联的 ES 提交一个任务,该组作为数据传递,即它可以将 P2 的实例提交给 E2、P3 或 P3 或 P4 到 E4,它选择哪一个取决于分组,P2、P3 和 P4 都做不同的事情。
假设它已经提交了一个 P2 的实例,P2 将通过将 P3 提交给 E3 或将 P4 提交给 E4 来完成处理。它是一种单向管道 P3 只能提交给 P4,一旦所有任务都提交给 P4 并且 P4 完成了所有处理完成的任务。
我们通过构造 ES1、ES2、ES3 和 ES4 来完成处理,向 P1 提交任务,然后在每个 ExecutorService 上依次调用 shutdown(),这样,直到 P1 完成提交所有组后,shutdown()才会返回,然后调用ES2 上的 shutdown() 在 ES2 清除 P2 任务等队列之前不会返回。
偶尔一切都会停止我假设某个进程正在阻止其他进程继续,所以在这一点上,我想要一种取消需要太长时间的进程以便其他进程可以继续的方法,这比它无限期挂起要好得多
答案更新
我尝试按照建议使用 invokeAny(),它有点工作。 如果 P1 向 E2 提交 P2 的一个实例,然后它会在完成之前等待,这没关系,因为当使用 submit() 时,它只是返回任何方式,它不会进一步处理,但有两个问题:
每个 ExecutorService 使用一个 500 的有界队列,其想法是如果 P2 比 P1 慢得多,我们就不会继续在 ES2 上堆叠东西并最终耗尽内存。所以现在 P1 在他们调用的任务完成之前不会完成队列实际上更小,因为它们不仅包含等待 ES2 上的插槽完成的任务,而且它们包含已经提交给 ES2 但正在等待它的任务完成。
管道是链式的,因此如果我们对从 P1 提交的任务以及从 P2、P3 和 P4 提交的任务使用 invokeAny,那么当一个任务从 P1 提交到 P2 时,它不会返回,直到从 E4 完成后续处理!
【问题讨论】:
-
您想为所有任务设置超时时间(如果所有任务都没有在给定时间内完成,则停止)还是分别为每个任务设置超时时间?
-
我希望任何需要太长时间才能停止而不影响其他任何任务的任务,即我不希望整个过程只停止那些花费太长时间的可调用对象(因为通过死锁它们阻止了应用程序作为一个整体从完成)
-
您可能应该查找死锁,特别是在 Java 的情况下。比如资源争用发生在哪里?它是一个实际的线程死锁吗?您的应用只是挂起并不意味着死锁。
-
好吧,也许这不是死锁,关键是我不知道它发生在哪里,事实上它不会发生在我身上,只是有时我只是想暂停一下。
-
取消!这里有一个示例:stackoverflow.com/questions/2758612/… 这将在超时任务上引发 InterruptedException。
标签: java executorservice