繁体   English   中英

Java CompletableFuture thenCompose 与几个异步任务

[英]Java CompletableFuture thenCompose with several async tasks

我有一个由 2 个异步步骤组成的过程。 第二步基于第一步的结果运行。 该过程在循环中启动。 挑战在于,第二步是由几个异步任务完成的,它们采用第一步迭代的 output。 第一步完成后,我想使用第一步结果启动 n 秒步骤。 我使用CompletableFuturethenCompose编写了这段代码。

它有效,但我发现它很复杂,我想知道这是否是正确的方法。 我特别想知道二级子任务的管理和使用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();
    }
}

不要在传递给thenCompose的 function 中执行CompletableFuture.supplyAsync当您可以使用直接的 thenApplyAsync 链接相同的依赖thenApplyAsync时。

通过thenApplyAsync链接依赖函数允许您在第一步完成之前获取表示这些步骤的CompletableFuture实例,因此您可以将它们全部收集到您的List中以等待它们在最后完成,并且不需要通过CompletableFuture.allOf创建复合期货CompletableFuture.allOf

public void test() {
    // Gather CompletableFutures to wait for them at the end
    List<CompletableFuture<?>> futures = new ArrayList<>();

    for (int i = 0; i < 10; i++) {
        int finalI = i;
        CompletableFuture<String> step1 = CompletableFuture.supplyAsync(() -> {
            logger.debug("Start step 1 - " + finalI);
            simulateLongProcessing();// just waits for 1 s
            logger.debug("End step 1 - " + finalI);
            return "step1 output - " + finalI;
        });
        // Second step : Chain several sub-tasks based on the result of the first step
        for (int j = 0; j < 50; j++) {
            final int finalJ = j;
            futures.add(step1.thenApplyAsync(s -> {
                logger.debug("Start - step 2 : " + s + " | " + finalJ);
                simulateLongProcessing();
                logger.debug("End - step 2 : " + s + " | " + finalJ);
                return "step2 output - " + s + " | " + finalJ;
            }));
        }
    }

    // Wait for the completion
    for (CompletableFuture<?> future : futures) {
        future.join();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM