相关疑难解决方法(0)

等到Future <T>的任何一个完成

我有很少的异步任务在运行,我需要等到它们中至少有一个完成(将来我可能需要等待N个任务中的util M完成).目前它们被呈现为未来,所以我需要类似的东西

/**
 * Blocks current thread until one of specified futures is done and returns it. 
 */
public static <T> Future<T> waitForAny(Collection<Future<T>> futures) 
        throws AllFuturesFailedException
Run Code Online (Sandbox Code Playgroud)

有这样的事吗?或类似的东西,对于Future来说不是必需的.目前我循环收集期货,检查一个是否完成,然后睡一段时间再检查一下.这看起来不是最好的解决方案,因为如果我长时间睡眠会增加不必要的延迟,如果我短时间睡眠则会影响性能.

我可以尝试使用

new CountDownLatch(1)
Run Code Online (Sandbox Code Playgroud)

并在任务完成时减少倒计时并执行

countdown.await()
Run Code Online (Sandbox Code Playgroud)

,但我发现只有控制未来的创造才有可能.这是可能的,但需要重新设计系统,因为当前创建任务的逻辑(将Callable发送到ExecutorService)与决定等待哪个Future分开.我也可以覆盖

<T> RunnableFuture<T> AbstractExecutorService.newTaskFor(Callable<T> callable)
Run Code Online (Sandbox Code Playgroud)

并建立RunnableFuture与附加监听能力的自定义实现时通知任务完成,然后附上这样的监听器所需的任务和使用CountDownLatch,但是这意味着我必须重写newTaskFor每一个ExecutorService的我用 - 可能会有执行它不会扩展AbstractExecutorService.我也可以尝试包装ExecutorService用于同样的目的,但是我必须装饰所有生产Futures的方法.

所有这些解决方案都可行,但看起来非常不自然.看起来我错过了一些简单的东西,比如

WaitHandle.WaitAny(WaitHandle[] waitHandles)
Run Code Online (Sandbox Code Playgroud)

在c#中.针对此类问题,是否有任何众所周知的解决方案?

更新:

最初我根本没有访问Future创建,所以没有优雅的解决方案.重新设计系统后,我得到了进入未来创造并能够countDownLatch.countdown()添加到执行过程中,那么我可以countDownLatch.await(),一切工作正常.谢谢其他答案,我不知道ExecutorCompletionService,并将它的确可以在相似的任务有帮助的,但在这个特殊的情况下,它不能被使用,因为一些期货在没有任何遗嘱执行人创造的 - 实际任务是通过网络发送到另一台服务器,远程完成并收到完成通知.

java concurrency multithreading

55
推荐指数
5
解决办法
3万
查看次数

标签 统计

concurrency ×1

java ×1

multithreading ×1