您正在提交作业并致电
join()
之后,等待异步作业完成。
流中间步骤是按元素执行的,这意味着中间步骤
.map(CompletableFuture::join)
一次在一个元素上运行(更糟糕的是,它是一个连续的流),而不确保所有元素都已完成提交步骤。这会导致线程在等待每个计算完成时阻塞。
在开始调用之前,必须强制提交所有作业
join()
在他们身上:
List<MyResult> results =
myInputList.stream()
.map(myService::getResultFuture)
.collect(Collectors.toList()).stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
如果你能表达出你想用
results
列表作为完成所有操作时要调用的操作,您可以以不阻止线程的方式实现该操作
join()
:
List<CompletableFuture<MyResult>> futures = myInputList.stream()
.map(myService::getResultFuture)
.collect(Collectors.toList());
CompletableFuture.allOf(futures.toArray(CompletableFuture<?>[]::new))
.thenRun(() -> {
List<MyResult> results = futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
});
它仍在呼叫
join()
检索结果,但此时,所有未来都已完成,因此调用方不会被阻止。