CompletableFuture 直接链接与单独链接时的行为不同
CompletableFuture behaves differently when chained directly vs individually
伙计们,我一直在我的项目中使用 CompletableFuture,我遇到了一个奇怪的行为。我想了解这种行为。请帮忙
场景 1:
在下面的代码中,输出是 我来自 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 个任务,那么该方法将变得太大.在这种情况下,我想首先将每个调用提取到一个方法中,但如果需要,最终提取到一个 class 中,但我无法完成场景 2 的所有这些原因。
想知道为什么方案 2 以不同的方式运行的概念或想法,以及是否有办法让它像方案 1 一样运行。请分享您的知识。谢谢。
首先,你有 哪个线程将执行那些 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
上,当它完成时,将 return "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;
}
伙计们,我一直在我的项目中使用 CompletableFuture,我遇到了一个奇怪的行为。我想了解这种行为。请帮忙
场景 1: 在下面的代码中,输出是 我来自 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 个任务,那么该方法将变得太大.在这种情况下,我想首先将每个调用提取到一个方法中,但如果需要,最终提取到一个 class 中,但我无法完成场景 2 的所有这些原因。
想知道为什么方案 2 以不同的方式运行的概念或想法,以及是否有办法让它像方案 1 一样运行。请分享您的知识。谢谢。
首先,你有 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
上,当它完成时,将 return "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;
}