java - 为什么 CompletableFuture 没有按顺序执行?
问题描述
我的目标是了解 CompletableFuture 是如何工作的。
我的预期结果:如果我这样做了CompletableFuture.runAsync().thenRun().thenRunAsync()
。该线程将按顺序执行runAsync() -> thenRun() -> thenRunAsync()
。
我的实际结果:序列是竞争条件。有时:
runAsync
->thenRunAsync+e
-> ...runAsync
->thenRun
-> ...
public class RunExample5 {
public static void main(String[] args) {
ExecutorService e = Executors.newSingleThreadExecutor(r -> new Thread(r, "sole thread"));
CompletableFuture<?> f = CompletableFuture.runAsync(() -> {
System.out.println("runAsync:\t" + Thread.currentThread());
LockSupport.parkNanos((int) 1e9);
}, e);
f.thenRun(() -> System.out.println("thenRun:\t" + Thread.currentThread()));
f.thenRunAsync(() -> System.out.println("thenRunAsync:\t" + Thread.currentThread()));
f.thenRunAsync(() -> System.out.println("thenRunAsync+e:\t" + Thread.currentThread()),
e);
LockSupport.parkNanos((int) 2e9);
e.shutdown();
}
}
解决方案
你需要
f.thenRun(() -> System.out.println("thenRun:\t" + Thread.currentThread()))
.thenRunAsync(() -> System.out.println("thenRunAsync:\t" + Thread.currentThread()))
.thenRunAsync(() -> System.out.println("thenRunAsync+e:\t" + Thread.currentThread()), e);
界面CompletableFuture
并不像您想象的那样工作。f
它本身不会跟踪对thenRun
or的每次调用thenRunAsync
并按顺序运行它们;相反,它会在主要工作完成后立即将所有内容视为可运行的thenRun
或thenRunAsync
同时可运行的。如果你想链接更复杂的工作序列,你需要使用thenRun
or的返回值thenRunAsync
——一个对象——CompletionStage
并调用thenRunAsync
它。
推荐阅读
- sharepoint-online - 在 SharePoint Online / O365 中自动化网站创建方面我们能走多远?
- java - 使用spring-cloud-stream发送rabbitmq消息时,无法指定发送的RoutingKey
- python - 无法从 Python 应用程序连接到 DataStax Enterprise 集群
- c# - 如何在我的 .Net Core Identity Web 应用程序中强制执行 2FA
- apache-nifi - 有没有办法在 Nifi 上使用 KV 过滤器来解析日志
- mysql - 如何使用 MySQL 在数字序列中查找下一个可用数字
- git - 如何在 git 中合并单个文件?
- cmake - Cmake 库目录
- kivy - 如何用kivy创建一个圆形按钮?
- sql - 使用列值作为 sqlite3 中的列