java - ExecutorService vs CompletableFuture
问题描述
我一直在尝试实现一个异步过程,其中父方法调用一个子方法,该子方法又会调用三种不同的方法。我希望所有这些过程都异步完成,即在子方法中的这三个调用并行进行之后,控件应该返回父方法并继续执行其余部分。
我有这段代码,经过测试可以正常工作。
public ReturnSomething parent(){
child();
...//rest to UI
}
private void child(){
ExecutorService executorService = Executors.newFixedThreadPool(3);
Runnable service1 = () -> {
MyFileService.service1();
};
Runnable service2 = () -> {
MyFileService.service2();
};
Runnable service3 = () -> {
MyFileService.service3();
};
executorService.submit(service1);
executorService.submit(service2);
executorService.submit(service3);
}
现在,我的领导要求我改用这个。
public ReturnSomething parent(){
child();
...//rest to UI
}
private void child(){
CompletableFuture.supplyAsync(() -> MyFileService.service1();
CompletableFuture.supplyAsync(() -> MyFileService.service2();
CompletableFuture.supplyAsync(() -> MyFileService.service3();
}
我知道 CompletableFuture 是 Java 8 的新功能,但是第二个代码比第一个代码更好吗?因为对于 ExecutorService,我没有调用“get()”方法,所以我不会等待 aysnc 响应。那么,有人可以解释一下有什么区别吗?
解决方案
在功能上,这两种方法或多或少是相同的:
- 您提交任务以供执行;
- 你不等待结果。
但是,从技术上讲,存在一些细微的差异:
- 在第二种方法中,您没有指定执行程序,因此它将使用 common
ForkJoinPool
。supplyAsync()
如果您不想这样做,则必须传递执行者作为第二个参数; CompletableFuture
API 允许轻松链接更多调用thenApply()
,thenCompose()
等等。因此它比简单Future
返回的更灵活ExecutorService.submit()
;- Using
CompletableFuture
允许child()
使用return CompletableFuture.allOf(the previously created futures)
.
关于可读性,这是一个偏好问题,但如果你想要等效的代码,CompletableFuture
一旦你对它进行了类似的格式化,这种方法可能会被认为可读性较差。相比:
executorService.submit(MyFileService::service1);
executorService.submit(MyFileService::service2);
executorService.submit(MyFileService::service3);
和
CompletableFuture.supplyAsync(MyFileService::service1, executorService);
CompletableFuture.supplyAsync(MyFileService::service2, executorService);
CompletableFuture.supplyAsync(MyFileService::service3, executorService);
推荐阅读
- r - 如何从不平衡的数据中创建一个新的平衡数据框,以确保随机选择记录?
- django - 我如何在 django 中创建一个也发送邮件的注册表单
- android - 如何使用 kotlin 从 onPostExecute() 方法更改活动
- validation - 不跨越矩阵边界的验证函数(迷宫)
- javascript - 在文件重命名时停止 VSCode 将 javascript 导入转换为 typescript 缓存
- javascript - 当页面加载时执行 JQuery 函数而不是 .keyup
- node.js - 如何告诉 Firefox Quantum 上的 Selenium Webdriver 使用具有身份验证和端口的代理?
- python - 带有 aiozmq 流的简单 PUB/SUB
- c# - C# Modbus帧拆分和存储程序
- visual-studio - 复制连接到 tfs 的项目