如何异步运行组合CompletableFutures



我想在应用程序启动时通过调用返回不同对象类型列表的不同服务来加载数据。每个服务都调用DAO类来读取一些数据。因此,我创建了个人CompletableFuture,如:

CompletableFuture<List<DTO1> future1 = CompletableFuture.supplyAsync(() -> service1.callMethod1());
CompletableFuture<List<DTO2> future2 = CompletableFuture.supplyAsync(() -> service2.callMethod2());
CompletableFuture<List<DTO3> future3 = CompletableFuture.supplyAsync(() -> service3.callMethod3());

并将它们组合为:

CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future1, future2, future3);

如果我做了这样的事情:

combinedFuture.thenRunAsync(()->future1.join(), future2.join(), future3.join())

然后我得到了编译时的错误。我是Java 8并发特性的新手,比如CompletableFuture,我想调用thenRunAsync会在不同的线程中运行每个future1,future2,future3。调用thenRunAsync是正确的方法吗?如果是,那么如何删除编译时的错误?

但如果我做了这样的事情:

Stream.of(future1, future2, future3)
.map(CompletableFuture::join)
.collect(Collectors.toList());

它正在返回List<? extends List<?>>,然后它似乎工作,但我应该打电话给.collect(Collectors.toList())吗?我并不关心这个组合结果,因为为了缓存目的,每个单独的方法调用都已经用@Cacheable进行了注释。此外,如果我做一些类似的事情:

Stream.of(future1, future2, future3)
.foreach(CompletableFuture::join);

它会在不同的线程中运行每个future1,future2,future3吗?如何在3个不同的线程中运行future1,future2,future3?有什么正确的方法可以异步运行这三个数据库调用吗?

CompletableFuture<List<DTO1> future1 = CompletableFuture.supplyAsync(() -> service1.callMethod1());
CompletableFuture<List<DTO2> future2 = CompletableFuture.supplyAsync(() -> service2.callMethod2());
CompletableFuture<List<DTO3> future3 = CompletableFuture.supplyAsync(() -> service3.callMethod3());

这段代码已经指示所有三个future在不同的线程上运行(假设公共池中至少有3个线程(。在其中一个调用join()只是指示调用线程在完成该任务时进行阻塞,并且不会改变3个调用并行进行的事实。编译的所有解决方案都是合理的。

最新更新