微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

CompletableFuture 在直接链接和单独链接时表现不同

如何解决CompletableFuture 在直接链接和单独链接时表现不同

我一直在我的项目中使用 CompletableFuture 并且我遇到了一个奇怪的行为。我想了解这种行为。请帮忙

场景 1: 在下面的代码中,输出I am from supply 我是第一个 thenApply 我是第二个 thenApply .. 正如预期的

public void callAll(){
        String calculateddistance = listBuildComp().stream()
                .map(CompletableFuture::join)
                .collect(Collectors.joining());
        System.out.println(calculateddistance);
    }
    private List<CompletableFuture<String>> listBuildComp(){
        List<CompletableFuture<String>> result = new ArrayList<>();
        result.add(buildComp());
        return result;
    }

    private CompletableFuture<String> buildComp(){
        CompletableFuture<String> workFlowWithServices =
                CompletableFuture.supplyAsync( () -> "I am from supply ")
        .thenApply( x -> {
            return x.concat(" I am the first thenApply ");
        })
        .thenApply( x -> {
            return x.concat(" I am the second thenApply ");
        });
        return workFlowWithServices;
    }

场景 2: 更改以下方法后,输出I am from supply 。经过进一步调查,我发现其余两个 thenApply 在他们自己的线程中运行

private CompletableFuture<String> buildComp(){
        CompletableFuture<String> workFlowWithServices =
                CompletableFuture.supplyAsync( () -> "I am from supply ");
        
        workFlowWithServices.thenApply( x -> {
            return x.concat(" I am the first thenApply ");
        });
        
        workFlowWithServices.thenApply( x -> {
            return x.concat(" I am the second thenApply ");
        });
        return workFlowWithServices;
    }

我对场景 2 感兴趣的原因是假设您正在链接 2 个任务,然后场景 1 没问题,但假设您想要链接 50 个任务,那么该方法会变得太大。在这种情况下,我想将每个调用提取一个方法中,但如果需要,最终提取一个类中,但我无法完成场景 2 的所有这些原因。

想知道关于为什么场景 2 的行为方式不同的概念或想法,以及是否有办法让它像场景 1 一样运行。请分享您的知识。谢谢。

解决方法

首先,您有 no guarantee 哪个线程将执行这些 thenApply,它很容易是 main

然后在您的示例中,您构建一个 CompletableFuture

CompletableFuture<String> workFlowWithServices =
       CompletableFuture.supplyAsync( () -> "I am from supply ");

链接一些动作:

    workFlowWithServices.thenApply( x -> {
        System.out.println("executing");
        return x.concat(" I am the first thenApply ");
    })

   ...

但您忽略 thenApply 的结果(这也是 CompletableFuture<String>)。当您 join 时,您在 joinworkFlowWithServices,当它完成时,将返回 "I am from supply "。完毕。您不会查询(您完全忽略)thenApply 中后续操作的结果,因此它们确实会执行,但结果已消失。

我不明白到底是什么阻止了你构建这样的东西,例如:

 private static CompletableFuture<String> buildComp2(){
    CompletableFuture<String> one =
            CompletableFuture.supplyAsync( () -> "I am from supply ");

    CompletableFuture<String> two = one.thenApply( x -> {
        System.out.println("executing");
        return x.concat(" I am the first thenApply ");
    });

    CompletableFuture<String> three = two.thenApply( x -> {
        return x.concat(" I am the second thenApply ");
    });
    return three;
}
 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。