繁体   English   中英

CompletableFuture.allOf() 在等待完成时是否比 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.

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