繁体   English   中英

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

[英]How to run multiple service calls in parallel using CompletableFuture?

我正在向用户返回以下回复

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

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

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

如果我做CompletableFuture.allOf(future1, future2, future3).join(); 或者我应该调用CompletableFuture.allOf(future1, future2, future3).get(); ? 即使我调用其中任何一个joinget那么我应该如何从中构造FinalResponseDTO 我是 Java 8 并发功能(例如CompletableFuture )的新手,我很困惑,因为每个未来的每个返回类型都不同,我应该如何获得所有这些期货的组合响应,然后构建我的最终 output?

来自CompletableFuture.allOf()的 Javadocs:

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

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

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

正如暗示的那样,您应该始终检查 Javadoc 以get()getNow()等方法的行为。 我在这里使用后者是为了避免异常处理,因为在allOf CompletableFuture 正常完成后,这些值将保证可用。

    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()上运行,因此提供您自己的执行程序是一个不错的选择,例如Executors.newCachedThreadPool()

CompletableFuture.supplyAsync(() -> action, executor);

而不是使用CompletableFuture.allOf ,您可以回退到CompletableFuture有点隐藏的 Applicative :

static <T, R> CompletableFuture<R> alsoApply(CompletableFuture<T> future,     CompletableFuture<Function<T, R>> f) {
    return f.thenCompose(future::thenApply);
}

使用这个助手 function 您可以在并行线程中执行期货:

CompletableFuture<String> future = alsoApply(
    CompletableFuture.supplyAsync(() -> "a"),
    CompletableFuture.supplyAsync(() -> "b")
.thenApply(b -> a -> a + b));

assertEquals("ab", future.get());

请参阅此问题和答案,了解它的来源以及它的工作原理和方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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