Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java CompletableFuture可与多个异步任务组合_Java_Concurrency_Completable Future - Fatal编程技术网

Java CompletableFuture可与多个异步任务组合

Java CompletableFuture可与多个异步任务组合,java,concurrency,completable-future,Java,Concurrency,Completable Future,我有一个由2个异步步骤组成的流程。第二步根据第一步的结果运行。这个过程是在一个循环中启动的。挑战在于,第二步是由几个异步任务完成的,这些任务获取第一步迭代的输出。第一步完成后,我想使用第一步结果启动n秒步骤。我使用CompletableFuture和然后compose制作了这段代码 这是可行的,但我发现它相当复杂,我想知道这是否是正确的方法。我特别想知道,管理第二级子任务和使用CompletableFuture.allOf使其成为单个CompletableFuture是否是正确的做法 publi

我有一个由2个异步步骤组成的流程。第二步根据第一步的结果运行。这个过程是在一个循环中启动的。挑战在于,第二步是由几个异步任务完成的,这些任务获取第一步迭代的输出。第一步完成后,我想使用第一步结果启动n秒步骤。我使用
CompletableFuture
然后compose
制作了这段代码

这是可行的,但我发现它相当复杂,我想知道这是否是正确的方法。我特别想知道,管理第二级子任务和使用
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();
    }
}
公共无效测试(){
//收集完整的未来,在最后等待它们
列表期货=新的ArrayList();
//第一步
对于(int i=0;i<10;i++){
int finalI=i;
CompletableFuture fut=CompletableFuture.SupplySync(()->{
调试(“开始步骤1-”+finalI);
simulateLongProcessing();//只需等待1秒
logger.debug(“结束步骤1-”+finalI);
返回“step1输出-”+最终结果;
})。然后撰写(s->{
List subFutures=new ArrayList();
//第二步:根据第一步的结果启动多个子任务
对于(int j=0;j<50;j++){
最终int finalJ=j;
CompletableFuture f=CompletableFuture.SupplySync(()->{
调试(“开始-第2步:“+s+”|“+finalJ”);
模拟长处理();
调试(“结束-第2步:“+s+”|“+finalJ”);
返回“step2输出-”+s+“|”+finalJ;
});
子未来。添加(f);
}
返回CompletableFuture.allOf(subFutures.toArray(新的CompletableFuture[0]);
});
期货.add(fut);
}
//等待完成
for(可完成的未来:未来){
future.join();
}
}

不要在传递给
然后合成的
函数中执行
可完成的未来。当您可以用一个直接的
然后应用同步
链接相同的依赖函数时,请在该函数中提供同步

通过
应用程序同步
链接相关函数,您可以在第一步完成之前获得表示这些步骤的
可完成的未来
实例,因此,您可以将它们全部收集到您的
列表中
,等待它们最终完成,而无需通过
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();
    }
}
公共无效测试(){
//收集完整的未来,在最后等待它们

List我认为使这个看起来复杂的是创建许多未来的循环。如果你重构这个方法,使嵌套的循环或
thencose
lambda转到一个单独的方法,它看起来会更简单。