如何解决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
时,您在 join
上 workFlowWithServices
,当它完成时,将返回 "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 举报,一经查实,本站将立刻删除。