java – 如何让Callable任务提交到ExecutorService超时

前端之家收集整理的这篇文章主要介绍了java – 如何让Callable任务提交到ExecutorService超时前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我将Callable任务(使用submit())提交给ExecutionService的实现.偶尔我似乎遇到了死锁,但无法在哪里或为什么会发生这种情况,所以我想在任务上设置超时,我不清楚它是怎么做到的?

我是不是该

>在提交任务和设置超时时,在ExecutionService上使用invokeAny()而不是submit().我使用submit()一次一个地提交许多任务,我是否可以像这样使用invokeAny(),我很谨慎,因为我无法理解为什么没有一个超时的submit()方法.
>在我的ExecutorService的构造函数修改keepAliveTime(但我认为这是在做其他事情
>修改我的实际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,ES3和ES4完成处理,将任务提交给P1,然后依次在每个ExecutorService上调用shutdown(),这样,在P1完成提交所有组之后,shutdown()将不会返回,然后调用shutdown()在ES2上,直到ES2清除了它的P2任务队列才会返回.

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

答案更新

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

>每个ExecutorService使用500的有界队列,其想法是如果P2比P1慢得多,我们就不会将内容堆叠到ES2上并最终耗尽内存.所以现在P1没有完成,直到他们调用的任务完成后,队列实际上更小,因为它们不仅包括等待ES2上的插槽完成的任务,而且它们包含已经提交给ES2但正在等待它的任务完.
>管道是链接的,所以如果我们在从P1提交的任务上使用invokeAny,从P2和P3和P4提交任务,那么当任务从P1提交到P2时,它将不会返回,直到后续处理从E4完成!

解决方法

您可以使用guava的MoreExecutors ListeningExecutorService.它不会神奇地解决你的问题,但可以提供一些帮助:

1)您可以为通过invokeAll调用的每个Callable设置超时.如果在给定时间内没有完成可调用,则应该将其杀死.

2)您可以创建所有ListenableFutures的全局映射,其中每个都将在创建时注册一个标志并在完成时清除该标志.通过这种方式,您可以知道哪些未来没有完成帮助缩小问题范围.

猜你在找的Java相关文章