当前位置: 首页 > 知识库问答 >
问题:

如何使用CompletableFuture并行运行多个服务调用?

燕翔飞
2023-03-14

我将以下响应返回给用户

class FinalResponseDTO {
    List<Service1ResponseDTO> service1ResponseDTO;
    Long totalCount;
    List<Service2ResponseDTO> service2ResponseDTO;
}

到目前为止,我正在进行三次连续调用来计算这个FinalResseDTO,每个调用都可以独立于其他调用运行。我尝试制作三种不同的CompletableFuture作为:

CompletableFuture<List<Service1ResponseDTO> future1 = CompletableFuture.supplyAsync(() -> service1.callMethod1());
CompletableFuture<Long> future2 = CompletableFuture.supplyAsync(() -> service2.callMethod2());
CompletableFuture<Service2ResponseDTO> future3 = CompletableFuture.supplyAsync(() -> service3.callMethod3());

如果我做了CompletableFuture。所有(未来1、未来2、未来3)。join() 或者我应该调用CompletableFuture。所有(未来1、未来2、未来3)。get() ?即使我调用了这些joinget中的任何一个,那么我应该如何从中构造FinalResponseDTO。我不熟悉Java 8并发特性,例如CompletableFuture,我很困惑,因为每个future的每个返回类型都不同,我应该如何获得所有这些future的组合响应,然后构造最终输出?


共有2个答案

漆雕成弘
2023-03-14
    CompletableFuture<List<Service1ResponseDTO> future1 = 
        CompletableFuture.supplyAsync(() -> service1.callMethod1());
    CompletableFuture<Long> future2 = 
        CompletableFuture.supplyAsync(() -> service2.callMethod2());
    CompletableFuture<List<Service2ResponseDTO>> future3 = 
        CompletableFuture.supplyAsync(() -> service3.callMethod3());

    CompletableFuture.allOf(future1, future2, future3).get();

    return new FinalResponseDTO(future1.join(), future2.join(), future3.join());

注意:supplyAsyncForkJoinPool上运行。commonPool()因此,提供您自己的执行器(例如执行器)是一个不错的选择。newCachedThreadPool()

CompletableFuture.supplyAsync(() -> action, executor);
龙哲
2023-03-14

来自CompletableFuture的Javadocs。anyOf()

返回一个新的CompletableFuture,该Future在所有给定CompletableFutures完成时完成。如果任何给定的CompletableFutures异常完成,那么返回的CompletableFutures也会这样做,CompletionException将此异常作为其原因。否则,给定的CompletableFutures的结果(如果有)不会反映在返回的CompletableFutures中,而是可以通过单独检查来获得。

因此,当组合CompletableFuture完成时,您可以通过应用构造对象的函数,使用简单构造函数检查值并构造最终响应对象:

CompletableFuture.allOf(future1, future2, future3).thenApply(v -> 
    new FinalResponseDTO(future1.getNow(null), future2.getNow(null), future3.getNow(null))
);

正如所暗示的,您应该始终检查Javadoc中的方法行为,例如get()vsgetNow()。我在这里使用后者是为了避免异常处理,因为在allOfCompletableFuture正常完成后,这些值将保证可用。

 类似资料:
  • 问题内容: 在这里,我需要同时执行,并在同一时间。 当我尝试在其上放置一个并行块时,由于在官方站点中这样提到,因此它引发了错误。 } 问题答案: 您不必将每个调用都放在阶段内的并行作业中,因此可以这样进行:

  • 我通过执行一些可调用项。如果线程列表只包含1个可调用的线程,那么我直接调用我的的方法。若列表包含超过1个可调用项,那个么我将通过线程池执行器并行执行所有这些线程。 我如何在Java8 CompletableFuture中实现这一点?如果增强了以避免阻塞,这将是一个加号。

  • 假设我有一种情况,我 ;调用两个存储库来获取项目。 当这两个都完成并反馈结果时,我怎样才能得到反馈呢?传统上,我会一个一个地调用这两个,然后再做剩下的逻辑。在这里,我想加快这个过程。 I ;试图做thenCombine()这样的事情,但两者都是不同的对象,我无法在这个lambda中写入逻辑。有谁能提出更好的方法吗?

  • 我正在使用 Kubernetes 作为容器编排器构建一个微服务应用程序。该应用程序现已启动并运行,但我有其他问题。那是在我的服务中,我每天都有一个计划任务运行,当服务部署时,将运行多个服务实例(通过设置副本编号),创建多个同时运行的任务。我期望的是只有一个服务任务实例将运行,而不是多个实例。有什么技术可以处理这种情况吗? 库伯内特斯 Asp.net核心构建微服务 CI/CD的基岩实现 Fabrik

  • 问题内容: 在我的我有这两个脚本: 每当我开始在Node.js中开发时,我必须 并行 运行这两个脚本。我想到的第一件事是添加第三个脚本,如下所示: …但这将等待完成再运行。 如何并行运行它们? 请记住,我需要查看以下命令。另外,如果您的解决方案涉及构建工具,则我宁愿使用,因为我已经在另一个项目中使用了它。 问题答案: 使用并发调用的包。 然后按以下步骤设置您的任务:

  • 在我的中有以下两个脚本: 每次在Node.js中开始开发时,我都必须并行运行这两个脚本。我首先想到的是添加第三个这样的脚本: ...但在运行之前,将等待完成。 我如何并行运行这些?请记住,我需要查看这些命令的。另外,如果您的解决方案涉及构建工具,我宁愿使用而不是,因为我已经在另一个项目中使用了它。