如何将可调用任务提交到ExecutorService超时

Pau*_*lor 7 java executorservice

我将Callable任务(使用submit())提交ExecutionService的实现.偶尔我似乎遇到了死锁,但无法在哪里或为什么会发生这种情况,所以我想在任务上设置超时,我不清楚它是怎么做到的?

我是不是该

  1. 在提交任务和设置超时时,在ExecutionService上使用invokeAny()而不是submit().我使用submit()一次一个地提交一个任务,我可以像这样使用invokeAny(),我很谨慎,因为我无法理解为什么没有一个超时的submit()方法.
  2. 在我的ExecutorService的构造函数中修改keepAliveTime(但我认为这是在做其他事情
  3. 修改我的实际Callable实现,但是如果它是死锁的,它就无法自我解锁.

选项1似乎是唯一可行的解​​决方案,但是它呢?

更多细节

我认为,如果有助于解决方案,可能需要更详细地解释该流程的工作原理.

可调用任务P1启动并在文件夹及其中的所有文件和文件夹上工作,并开始将歌曲分组,在ExecutorService ES1中运行,只有一个P1实例提交给ES1.

我们还有三个其他可调用类:P2,P3和P4 - 每个类都有自己的相关Executor服务,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()将不会返回,然后调用shutdown()在ES2上,直到ES2清除了它的P2任务队列才会返回.

一切都停止了我假设一些过程阻止其他进程继续进行,所以此时我想要一种取消过程的方法,这种过程需要太长时间,以便其他人可以继续,这远远不如它只是无限期地悬挂

答案更新

我按照建议尝试使用invokeAny(),它有点工作.如果P1将一个P2实例提交给E2,那么它在完成之前就会等待,这是好的,因为当使用submit()时它只返回它没有进一步处理的任何方式,但有两个问题:

  1. 每个ExecutorService使用500的有界队列,其想法是如果P2比P1慢得多,我们就不会将内容堆叠到ES2上并最终耗尽内存.所以现在P1没有完成,直到他们调用的任务完成后,队列实际上更小,因为它们不仅包括等待ES2上的插槽完成的任务,而且它们包含已经提交给ES2但正在等待它的任务完.

  2. 管道是链接的,所以如果我们在从P1提交的任务上使用invokeAny,从P2和P3和P4提交任务,那么当任务从P1提交到P2时,它将不会返回,直到后续处理从E4完成!

Pau*_*lor 0

一旦我做了一些修改,@PhilipWhitehouse 的评论就起作用了。

总之,创建一个自定义 ThreadPool,封装 ScheduledExecutorPool,以便在提交任务时设置超时。

完整解决方案在这里:

如何使用此自定义 ExecutorService 使关闭正常工作?