[英]CompletableFuture allof(..).join() vs CompletableFuture.join()
[英]Has CompletableFuture.allOf() any advantage over a loop with CompletableFuture.join() when just waiting for completion?
我正在对我的数据库进行多次异步调用。 我将所有这些异步调用存储在List<CompletableFuture<X>> list
。 我想将所有结果收集在一起,所以我需要等待所有这些调用完成。
一种方法是创建一个CompletableFuture.allOf(list.toArray(...))...
另一种方法是使用: list.stream.map(cf -> cf.join())...
我只是想知道创建全局 CompletableFuture 并等待它完成(当所有单个 CompletableFuture 完成时)与直接等待单个 CompletableFuture 完成相比是否有任何优势。
我看到了使用allOf
两个优点,现在我想念的可能还有更多。 考虑这个例子:
static CompletableFuture<String> one() {
return CompletableFuture.supplyAsync(() -> {
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
throw new RuntimeException("failure in one");
});
}
static CompletableFuture<String> two() {
return CompletableFuture.supplyAsync(() -> {
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(5));
System.out.println("two is done");
return "two";
});
}
你称他们为:
List<CompletableFuture<String>> futures = new ArrayList<>(2);
futures.add(one());
futures.add(two());
futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
运行它以查看two is done
不是输出的一部分,这意味着one
失败的事实,甚至没有触发two
。 另一方面,如果您将代码更改为:
List<CompletableFuture<String>> futures2 = new ArrayList<>(2);
futures2.add(one());
futures2.add(two());
CompletableFuture.allOf(futures2.toArray(newCompletableFuture[0])).join();
然后运行它,你会看到, two is done
是输出的一部分。 你真的应该仔细阅读allOf
的文档。
我看到的另一个区别是流解决方案确实是阻塞的。 流将被阻塞,直到所有操作完成,与:
CompletableFuture.allOf(futures2.toArray(new CompletableFuture[0]))
没有join
显然,你可以返回一个CompletableFuture
和链依赖动作到它上面:
CompletableFuture<Void> all = CompletableFuture.allOf(futures2.toArray(new CompletableFuture[0]));
all.whenComplete((x, y) -> {....})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.