【发布时间】:2019-11-14 17:04:17
【问题描述】:
我有一个由 2 个异步步骤组成的过程。第二步基于第一步的结果运行。该过程在循环中启动。挑战在于,第二步是由几个异步任务完成的,它们获取第一步迭代的输出。第一步完成后,我想使用第一步结果启动 n 秒步骤。我使用CompletableFuture 和thenCompose 编写了这段代码。
它有效,但我发现它很复杂,我想知道这是否是正确的方法。我特别想知道二级子任务的管理和使用CompletableFuture.allOf使其像单个CompletableFuture是正确的做法。
public void test() {
// Gather CompletableFutures to wait for them at the end
List<CompletableFuture> futures = new ArrayList<>();
// First steps
for (int i = 0; i < 10; i++) {
int finalI = i;
CompletableFuture<Void> fut = CompletableFuture.supplyAsync(() -> {
logger.debug("Start step 1 - " + finalI);
simulateLongProcessing();// just waits for 1 s
logger.debug("End step 1 - " + finalI);
return "step1 output - " + finalI;
}).thenCompose(s -> {
List<CompletableFuture> subFutures = new ArrayList<>();
// Second step : Launch several sub-tasks based on the result of the first step
for (int j = 0; j < 50; j++) {
final int finalJ = j;
CompletableFuture<String> f = CompletableFuture.supplyAsync(() -> {
logger.debug("Start - step 2 : " + s + " | " + finalJ);
simulateLongProcessing();
logger.debug("End - step 2 : " + s + " | " + finalJ);
return "step2 output - " + s + " | " + finalJ;
});
subFutures.add(f);
}
return CompletableFuture.allOf(subFutures.toArray(new CompletableFuture[0]));
});
futures.add(fut);
}
// Wait for the completion
for (CompletableFuture future : futures) {
future.join();
}
}
【问题讨论】:
-
我认为让这看起来复杂的原因是循环创建了许多未来。如果重构方法,使嵌套循环或
thenComposelambda 转到单独的方法,它看起来会更简单。
标签: java concurrency completable-future