我有两个服务电话:
String call1() { ... return "ok"; }
void call2(String) { ... }
我知道带有回调的 CompletableFuture 的基本方法是这样的
CompletableFuture<Void> future = CompletableFuture
.supplyAsync(() -> call1())
.thenAccept(s -> call2(s));
future.join();
如果我将两个链式 CompletableFutures 分开会怎样,例如:
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> call1());
CompletableFuture<Void> future2 = future1.thenAccept(s -> call2(s));
future1.join(); // will call2 be executed at this time?
这与在 future2 上调用 join() 有什么不同吗:
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> call1());
CompletableFuture<Void> future2 = future1.thenAccept(s -> call2(s));
future2.join();
如果我对两个 futures 都调用 join() 会怎样?
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> call1());
CompletableFuture<Void> future2 = future1.thenAccept(s -> call2(s));
future1.join();
future2.join();
从运行我的示例代码来看,它们似乎都是一样的。但我觉得某处可能出了问题。谢谢!
最佳答案
它们不一样。
简而言之,你可以看成future1
和 future2
保留不同任务的结果(即使 future2
使用 future1
的结果,这是一个不同的 future )。
future1.join()
将阻塞直到 () -> call1()
结束,和future2
到那时才会开始任务。 future2.join()
会等到s -> call2(s)
完成了。
What if I separate the two chained CompletableFutures, like:
就任务执行而言,这没有区别。这要么是样式问题,要么仅在需要分别使用两个 future 对象时才重要。
What if I call join() on both of the futures?
在这种情况下调用 future1.join()
是多余的因为你在两者之间没有做任何事情.join
电话。如果您想“在任务 1 完成之后和任务 2 完成之前”执行某些操作,这将是有意义的。
不过,在这种情况下,调用 future2.join()
就够了。
下面的代码片段应该显示它的行为方式:
public static void main(String[] args) {
CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> delay());
CompletableFuture<Void> future2 = future1.thenRun(() -> delay());
long start = System.currentTimeMillis();
future1.join();
System.out.println("Future 1 done. Waiting for future 2: "
+ (System.currentTimeMillis() - start));
future2.join();
System.out.println("Future 2 complete: "
+ (System.currentTimeMillis() - start));
}
static void delay() {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
实际上,这段代码输出:
Future 1 done. Waiting for future 2: 5001
Future 2 complete: 10001
但是当你删除 future1.join()
,输出变为:
Future 2 complete: 10001
这仅仅意味着 future1.join()
是多余的,除非你在两个 futures 的完成之间有要执行的操作
关于java - 将始终执行 CompletableFuture 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52125603/