我面临一个问题,我正在顺序执行两个 CompletableFuture 对象。我的意图是让第一个完成,然后才开始执行第二个。所以换句话说,第二个取决于第一个的完成。
我无法分享确切的代码,但这是我正在做的事情的简化版本:
public static void main() {
Set<Object> firstSet = /* ... */
Set<Object> secondSet = /* ... */
CompletableFuture<Void> firstFuture = getFuture(firstSet);
CompletableFuture<Void> secondFuture = getFuture(secondSet);
// Want to ensure that secondFuture does not begin executing until
// all of the futures in firstFuture have completed
firstFuture.join();
secondFuture.join();
}
CompletableFuture<Void> getFuture(Set<Object> listOfObjects) {
List<CompletableFuture<Void>> futures = listOfObjects
.stream()
.map(object -> CompletableFuture.runAsync(getRunnableForObject(object), executorService))
.collect(Collectors.toList());
CompletableFuture<Void> future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
return future;
}
Runnable getRunnableForObject(Object obj) {
// assume this returns a custom runnable whose execution behavior depend on the object parameter
}
运行代码时,我发现有时在执行 firstFuture.join() 期间打印的日志的时间戳比在 secondFuture.join() 期间打印的某些日志的时间戳晚。我的期望是我们永远不会看到在 secondFuture 期间打印的任何日志出现在 firstFuture 期间打印的任何日志之前。
我认为 firstFuture.join() 确保未来在同步移动到 secondFuture.join() 之前完整完成,但也许我理解错了。有人可以建议吗?
此代码启动两组后台任务,因此它们同时进行:
CompletableFuture<Void> firstFuture = getFuture(firstSet);
CompletableFuture<Void> secondFuture = getFuture(secondSet);
确保第一/第二顺序的简单方法只需将这些行切换为:
CompletableFuture<Void> firstFuture = getFuture(firstSet);
firstFuture.join();
CompletableFuture<Void> secondFuture = getFuture(secondSet);
secondFuture.join();