public class Test {
public static CompletableFuture<Integer> firstMethod(int x) {
// Assume this method completes in 8sec.
return CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("In first method");
return x + 10;
});
}
public static CompletableFuture<Integer> secondMethod(int y) {
System.out.println("This line will be printed only when firstMethod get completed?");
return CompletableFuture.supplyAsync(() -> {
System.out.println("In second method");
return y + 10;
});
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
firstMethod(5)
.thenApply(fromfirst -> secondMethod(fromfirst))
.thenAccept(x -> System.out.println(x));
}
}
Do
firstMethod
必须完成,然后 thenApply()
方法才有机会运行。然后我可以说,只有当 thenApply()
完成执行时,在 firstMethod
内执行的任何代码才有机会。所以它的行为是同步的,就像 A 完成然后 B 运行一样。
如果是这种情况,为什么thenApply()
在单独的线程上运行?
我的假设: 我在想的是,无论之前的方法是否完成,
thenApply()
都应该运行。但想知道,例如,当需要第一个方法的输出作为thenApply()
中第二个方法的输入时会发生什么。
然后应用(函数 fn)
返回一个新的CompletionStage,当该阶段正常完成时,将使用该阶段的结果作为参数来执行 提供的功能。
重要的是此阶段完成时。
thenApply()
在单独的线程上运行。谁说的?
我怀疑您对最终输出显示类似
java.util.concurrent.CompletableFuture@6ad3e7be[Not completed]
的内容感到困扰。当您将 async 计算嵌入到 CompletionStage
中时,可能会有一些异步计算,但不是您想象的那样。
fromfirst -> secondMethod(fromfirst)
在交付 firstMethod
结果之后进行排序,从这个角度来看,secondMethod
构造 async 计算的事实并不重要。
将第一级的输出发送到第二级与将第一级标记为
Completed
之间可能存在延迟,仅此而已。在最后一次打印中添加一些等待,看看:
.thenAccept(x -> {
try {
Thread.sleep(1000); // wait a little bit
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(x);
});
因为可能有足够的时间正确标记所有内容,您会看到
java.util.concurrent.CompletableFuture@6ad3e7be[Completed normally]
您也可以尝试加入:
.thenAccept(x -> {
int i = x.join(); // synchronous waiting of the end and get the result.
System.out.println(x +" ------ "+ i);
});