首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在等待完成时,CompletableFuture.allOf()比使用CompletableFuture.join()的循环有什么优势吗?

在等待完成时,CompletableFuture.allOf()比使用CompletableFuture.join()的循环有什么优势吗?
EN

Stack Overflow用户
提问于 2021-10-29 10:15:38
回答 1查看 880关注 0票数 3

我正在对数据库进行多个异步调用。我将所有这些异步调用存储在List<CompletableFuture<X>> list上。我想收集所有的结果,所以我需要等待所有这些调用完成。

一种方法是创建一个CompletableFuture.allOf(list.toArray(...))...

另一种方法是使用:list.stream.map(cf -> cf.join())...

我只是想知道,与直接等待单个CompletableFuture完成相比,创建全局CompletableFuture并等待它完成(当所有单独的CompletableFuture都完成时)是否有什么好处。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-31 07:47:55

无论哪种方式,main线程都会被阻塞。

代码语言:javascript
运行
复制
static CompletableFuture<Void> getFailingCF() {
    return CompletableFuture.runAsync(() -> {
        System.out.println("getFailingCF :: Started getFailingCF.. ");
        throw new RuntimeException("getFailingCF:: Failed");
    });
}

static CompletableFuture<Void> getOkCF() {
    return CompletableFuture.runAsync(() -> {
        System.out.println("getOkCF :: Started getOkCF.. ");
        LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(3));
        System.out.println("getOkCF :: Completed getOkCF.. ");
    });
}

public static void main(String[] args) {
     List<CompletableFuture<Void>> futures = new ArrayList<>();
     futures.add(getFailingCF());
     futures.add(getOkCF());
      
     // using CompletableFuture.allOf
     var allOfCF = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
     
     allOfCF.join();
    
     // invoking join on individual CF
     futures.stream()
            .map(CompletableFuture::join)
            .collect(Collectors.toList());
 }

在上面的代码片段中,区别在于处理异常:CompletableFuture.allOf(..)包装任何CompletableFuture抛出的异常,同时允许其余的线程(执行CompletableFuture)继续它们的执行。

list.stream.map(cf -> cf.join())...方式立即抛出异常并终止应用程序(以及列表中执行CFs的所有线程)。

请注意,在join()上调用allOf也会引发包装异常。它还将终止该应用程序。但是,到目前为止,与list.stream.map(cf -> cf.join())...不同的是,剩下的线程已经完成了它们的处理。

allOfCF.whenComplete(..)是处理所有CFs的执行结果(正常或异常)的优雅方法之一:

代码语言:javascript
运行
复制
 allOfCF.whenComplete((v, ex) -> {
     System.out.println("In whenComplete...");
     System.out.println("----------- Exception Status ------------");

     System.out.println(" 1: " + futures.get(0).isCompletedExceptionally());
     System.out.println(" 2: " + futures.get(1).isCompletedExceptionally());
 });

list.stream.map(cf -> cf.join())...方式中,需要用try/catch包装join()调用。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69767216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档