我不明白这里发生了什么 CompletableFuture/supplyAsync。
如果我从先前实例化的 CompletableFuture 对象调用 supplyAsync
方法,它永远不会完成:
public static void ex1() throws ExecutionException, InterruptedException {
final CompletableFuture<String> cf = new CompletableFuture<>();
cf.supplyAsync(() -> {
System.out.println("Main.m3");
return "Main";
});
System.out.println("Start: cf = " + cf);
final String value = cf.get();
System.out.println("End: value = " + value);
}
这是输出:
Start: cf = java.util.concurrent.CompletableFuture@5b480cf9[Not completed]
Main.m3
如您所见,System.out.println("End: cf = "+ cf);
永远不会执行。
为了让它运行,我需要在 supplyAsync 的主体中放置一个 complete(my value)
。
但是如果我在创建 CompletableFuture 时直接调用 supplyAsync
(或通过调用静态 CompletableFuture.supplyAsync
):
public static void ex2() throws ExecutionException, InterruptedException {
final CompletableFuture<String> cf = new CompletableFuture<>()
.supplyAsync(() -> {
System.out.println("Main.m3");
return "Main";
});
System.out.println("Start: cf = " + cf);
final String value = cf.get();
System.out.println("End: value = " + value);
}
它按预期工作。你可以在这里看到输出:
Start: cf = java.util.concurrent.CompletableFuture@5b480cf9[Not completed]
Main.m3
End: value = Main
所以我的问题是:这是为什么?有什么我想念的吗?
最佳答案
supplyAsync
是 static
返回新 CompletableFuture
的方法并且不应通过实例调用它。
在第一种情况中,您正在调用 get()
在 CompletableFuture
上从未开始任何事情。
事实上,您会注意到您的程序在调用 ex1()
时将保留在 pending
中永远的状态。正因为如此,它永远无法执行下一行,打印出结果 Main
。 (并行计算的另一个 Future
)。
重点是您不存储第二个 CompletableFuture
任何地方。所以你不可能调用正确的 get()
.
在您的第二种情况中,您正在构建返回值为 supplyAsync
的实例,然后将其存储在 cf
中.这是构建 CompletableFuture
的正确方法. (new CompletableFuture<>()
部分是多余的;事实上,您可以立即使用 supplyAsync
为它分配一个新实例)。
当您调用 get()
时因此,您等待合适的CompletableFuture
返回其结果。
关于java - CompletableFuture.supplyAsync 与新的 CompletableFuture(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48906538/