![](/img/trans.png)
[英]Only execute CompletableFuture callback when status of result is completed
[英]CompletableFuture callback not called if completed manually
在CompletableFuture的这个基本示例中,我异步运行了一个任务,当它完成时,应该触发一个异步回调。
在我开始运行任务后一秒钟,在它完成之前,我完成了它。 之后,我不再看到它运行异步回调。
public static void main(String[] args) throws InterruptedException {
runTask();
Thread.sleep(1000);
completableFuture.complete("Test");
Thread.sleep(4000);
}
public static void runTask() {
completableFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("Running...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("...finished");
return "finished task";
})
.thenApplyAsync(s -> {
System.out.println("Apply on result: " + s);
return "Result: " + s;
})
}
结果是:
Running...
...finished
问题是,如果我添加另一个回调,那么它会运行第一个而不是第二个。
.thenApplyAsync(s -> {
System.out.println("Second apply with result: " + s);
return "Result: " + s;
})
那么结果是:
Running...
...finished
Apply on result: finished task
阅读文档后,我了解到所有回调都会被调用,即使未来是手动完成的。 我在这里错过了什么吗?
我想如果你写得稍微不同,它应该是有道理的:
public static void runTask() {
CompletableFuture<String> one = CompletableFuture.supplyAsync(() -> {
System.out.println("Running...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("...finished");
return "finished task";
});
CompletableFuture<String> two = one.thenApplyAsync(s -> {
System.out.println("Apply on result: " + s);
return "Result: " + s;
});
completableFuture = two;
}
所以,在你的情况下, one
开始就好了,但是在two
甚至可以开始之前,你发出completableFuture.complete("Test");
. 因此,当one
完成时, thenApplyAsync
没有任何内容,因为那个已经完成了。
当您再添加一个阶段时,您基本上会得到:
....
CompletableFuture<String> two = one.thenApplyAsync(s -> {
System.out.println("Apply on result: " + s);
return "Result: " + s;
});
CompletableFuture<String> three = two.thenApplyAsync(s -> {
System.out.println("Second apply with result: " + s);
return "Result: " + s;
});
completableFuture = three;
你可能会看到这里发生了什么,甚至不用我解释。
为此,我看不出文档在哪里可以清楚地说明这一点。 我想我们需要通过以下方式在package 文档中看到这一点:
当两个或更多线程尝试完成、完成异常或取消 CompletableFuture 时,只有其中一个成功。
这在某种程度上意味着,如果某个阶段尚未开始,但由其他人完成,则在外部complete
它; 那个阶段根本不会运行。 这是有道理的,但 package 文档可能更清楚,imo。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.