我有一个方法,可以返回期货的列表
List<Future<O>> futures = getFutures();
现在我想等待,直到所有的future都成功完成处理,或者future返回其输出的任何任务抛出异常。即使一项任务引发异常,等待另一项任务也没有意义。
简单的方法是
wait() {
For(Future f : futures) {
try {
f.get();
} catch(Exception e) {
//TODO catch specific exception
// this future threw exception , means somone could not do its task
return;
}
}
}
但这里的问题是,例如,如果第四个期货抛出异常,那么我将不必要地等待前三个期货可用。
如何解决这个问题?会以任何方式倒数闩锁帮助吗?我无法使用FutureisDone
,因为java文档说
boolean isDone()
Returns true if this task completed. Completion may be due to normal termination, an exception, or cancellation -- in all of these cases, this method will return true.
在Java 8中使用CompletableFuture
// Kick of multiple, asynchronous lookups
CompletableFuture<User> page1 = gitHubLookupService.findUser("Test1");
CompletableFuture<User> page2 = gitHubLookupService.findUser("Test2");
CompletableFuture<User> page3 = gitHubLookupService.findUser("Test3");
// Wait until they are all done
CompletableFuture.allOf(page1,page2,page3).join();
logger.info("--> " + page1.get());
如果您使用的是Java 8,那么使用CompletableFuture和CompletableFuture可以更轻松地实现这一点。allOf,它仅在完成所有提供的CompletableFutures之后应用回调。
// Waits for *all* futures to complete and returns a list of results.
// If *any* future completes exceptionally then the resulting future will also complete exceptionally.
public static <T> CompletableFuture<List<T>> all(List<CompletableFuture<T>> futures) {
CompletableFuture[] cfs = futures.toArray(new CompletableFuture[futures.size()]);
return CompletableFuture.allOf(cfs)
.thenApply(ignored -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList())
);
}
一旦期货准备就绪,您可以使用CompletionService接收期货,如果其中一个抛出异常,则取消处理。比如:
Executor executor = Executors.newFixedThreadPool(4);
CompletionService<SomeResult> completionService =
new ExecutorCompletionService<SomeResult>(executor);
//4 tasks
for(int i = 0; i < 4; i++) {
completionService.submit(new Callable<SomeResult>() {
public SomeResult call() {
...
return result;
}
});
}
int received = 0;
boolean errors = false;
while(received < 4 && !errors) {
Future<SomeResult> resultFuture = completionService.take(); //blocks if none available
try {
SomeResult result = resultFuture.get();
received ++;
... // do something with the result
}
catch(Exception e) {
//log
errors = true;
}
}
我认为,如果其中一个任务出现错误,您可以进一步改进以取消任何仍在执行的任务。
问题内容: 我有一种返回List期货的方法 现在,我要等待,直到所有期货都成功完成处理,或者所有由期货返回输出的任务都引发异常。即使一项任务引发异常,也没有必要等待其他期货。 简单的方法是 但是这里的问题是,例如,如果第4个期货抛出异常,那么我将不必要地等待前3个期货可用。 如何解决呢?会以任何方式倒计时闩锁帮助吗?我无法使用Future,isDone因为Java文档说 问题答案: 你可以使用Co
我想运行相同类型的任务(工作线程),但一次不超过一定数量的任务。当任务完成时,其结果是新任务的输入,然后可以启动该任务。 有没有好的方法可以在C 11中使用异步/未来范式来实现这一点? 乍一看,它看起来很简单,你只是生成多个任务: 然后,运行以获取任务的异步结果。 然而,这里的问题是,未来的对象必须存储在某种队列中并一个接一个地等待。但是,可以一遍又一遍地迭代未来的对象,检查它们中的任何一个是否准
我希望像下面这样的代码可以等待这两种未来,但是没有。 我以为< code>seq.onComplete会在完成自身之前等待它们全部完成,但事实并非如此;它会导致: 在scala.concurrent.Future的源代码中有点难以遵循,我想知道如何实现等待(动态大小的)序列的所有原始未来的并行,或者这里可能有什么问题。 编辑:相关问题:https://worldbuilding.stackexch
我正在尝试执行一些相互引用作为外键的查询,因此我必须等到外部未来完成。此算法放置在返回未来的函数中。 运行它时,我得到了这个: === TO CLIENT === 已完成存档 已完成全部 === TO CLIENT === 失败的 单词已完成 的单词 已完成 标记在博客中 完成投票 所以我的问题是,我怎么能等到未来的< code>mysql完成它的“childs”(在< code>whenComp
我想利用Tokio的运行时来处理可变数量的异步期货。由于在编译时期货的计数是未知的,因此 FuturesUnorderd 似乎是我的最佳选择(像 这样的宏需要在编译时指定你的分支;join_all可能是可能的,但是当顺序无关紧要时,文档建议“在很多情况下”FuturesUnordered)。 这个片段的逻辑是一个recv()循环,它被推送到期货桶中,应该一直运行。当新数据到达时,它的解析/处理也被
是否有一种方法可以在不阻塞事件循环的情况下等待一个未来完成? 我知道这个错误通常意味着什么,但我不知道在这种情况下...我试图在谷歌上搜索它,但没有找到任何关于将哪份清单放在哪里的明确解释。和以前一样,除非是强制性的,我更喜欢一次学一件事。 那么,回到这个问题:“基本”Vert.x是否有一种方法可以在事件循环不受干扰的情况下等待未来?