[英]CompletableFuture - Run multiple rest calls in parallel and get different result
[英]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();
? 即使我调用其中任何一个join
或get
那么我应该如何从中构造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());
注意: supplyAsync
在ForkJoinPool.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.