简体   繁体   English

等待两个 Futures/Runnables/Callables 中的任何一个完成?

[英]Wait for any of two Futures/Runnables/Callables to complete?

How can I add tasks, two at a time, to an Executor (or similar) and then wait for any of the two to finish (ie the fastest), while the other one, as well as previously started tasks, continues in the background?我如何一次添加两个任务到一个 Executor(或类似的),然后等待两个中的任何一个完成(即最快的),而另一个,以及之前启动的任务,在后台继续?

I know that a CompletionService offers something similar but with that one all I can do is wait for the next one to complete, with .take() .我知道 CompletionService 提供了类似的东西,但我所能做的就是等待下一个完成,使用.take() In my case that might be from a previous scheduling and not one of the ones I need to wait for.在我的情况下,这可能来自之前的安排,而不是我需要等待的安排之一。

In pseudo code I'd like在伪代码中我想要

ExecutorService executorService = Executors.newFixedThreadPool(100);
Future<?> one = executorService.submit(() -> oneWay());
Future<?> two = executorService.submit(() -> orAnother());

Future theFirstOneToFinish = waitFor(one, two);
// one done, the other one keeps on working
return theFirstOneToFinish;

A CompletionService oversees only those tasks that it submits. CompletionService只监督它提交的那些任务。 In other words, you can create a new one for every pair of tasks you submit and call take() to retrieve the first one that completes.换句话说,您可以为您提交的每对任务创建一个新任务,并调用take()来检索第一个完成的任务。

If you're using ExecutorCompletionService , create a new instance wrapping your ExecutorService , submit two tasks, and call take() .如果您正在使用ExecutorCompletionService ,请创建一个包装您的ExecutorService的新实例, submit两个任务,然后调用take()

For example:例如:

public Future<String> submitPair(ExecutorService executorService) throws InterruptedException {
    ExecutorCompletionService<String> ecs = new ExecutorCompletionService<>(executorService);
    ecs.submit(() -> oneWay());
    ecs.submit(() -> orAnother());
    return ecs.take();
}

No additional cleanup is required for the ExecutorCompletionService . ExecutorCompletionService不需要额外的清理。

Use CompletableFuture .使用CompletableFuture

ExecutorService executorService = Executors.newFixedThreadPool(100);
CompletableFuture<?> one = CompletableFuture.supplyAsync(() -> oneWay(),  executorService);
CompletableFuture<?> two = CompletableFuture.supplyAsync(() -> orAnother(),  executorService);

return CompletableFuture.anyOf(one, two);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM