2 回答
TA贡献1862条经验 获得超7个赞
它们不一样。
简而言之,您可以将其视为future1并future2保存不同任务future2的结果(即使使用 的结果future1,也是不同的未来)。
future1.join()将阻塞直到() -> call1()结束,并且future2直到那时才开始任务。future2.join()将等到s -> call2(s)完成。
如果我将两个链接的 CompletableFuture 分开会怎样,例如:
就任务执行而言,这没有区别。这要么是风格问题,要么仅在您需要分别使用两个未来对象时才重要。
如果我在两个期货上都调用 join() 怎么办?
在这种情况下调用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()是多余的,除非您在两个期货完成之间执行操作
TA贡献1829条经验 获得超6个赞
的supplyAsync和thenAccept方法应在一个单独的线程自动根据文档执行:
所有没有显式 Executor 参数的异步方法都使用 ForkJoinPool.commonPool() 执行
在您的示例中,唯一的区别是您的线程在由于加入而继续之前等待不同的事件。这是细分:
CompletableFuture<Void> future = CompletableFuture
.supplyAsync(() -> call1())
.thenAccept(s -> call2(s));
future.join();
这将等到call2完成,因为这是thenAccept方法返回的未来。
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> call1());
CompletableFuture<Void> future2 = future1.thenAccept(s -> call2(s));
future1.join(); // will call2 be executed at this time?
这只会等到call1完成并继续。 call2仍然会被执行。
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> call1());
CompletableFuture<Void> future2 = future1.thenAccept(s -> call2(s));
future2.join();
这与第一个相同。
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> call1());
CompletableFuture<Void> future2 = future1.thenAccept(s -> call2(s));
future1.join();
future2.join();
调用future1.join()在call1完成时结束,然后future2.join()在call2完成时结束。这在功能上也应该与第一个相同。
添加回答
举报