java - 将始终执行 CompletableFuture 回调

标签 java completable-future

我有两个服务电话:

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();

从运行我的示例代码来看,它们似乎都是一样的。但我觉得某处可能出了问题。谢谢!

最佳答案

它们不一样。

简而言之,你可以看成future1future2保留不同任务的结果(即使 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/

相关文章:

java - JTextField,使用Document Filter过滤整数和句号

java - QuickBooks Online Java SDK DataServiceexecuteBatch() 导致 NullPointerException

java - 使用 compose 创建 CompletableFutures 的链接列表

java - 如何使用 CompletableFuture 异步发送多个请求并返回成功?

java - CompletableFuture 的 whenComplete 签名

java - 如何将背景图像和 HTML 内容合并为一个可下载图像

java - android-support-v7-appcompat 库项目将无法运行

java - 如何检查列表中的列表是否具有相同的长度

multithreading - 如何从与其关联的线程中发出 CompletableFutures 已完成或已取消的信号?

java - Guice 在执行 CompletableFuture 时抛出 OutOfScopeException