java - 获取 CompletableFuture 的结果
问题描述
我正在使用 completablefuture 从 springboot 应用程序中的异步线程返回。我的实现如下。据我了解,应该为列表中的每个项目启动一个新线程,并且应该并行处理。我知道 .get 会阻止执行,但由于它是并行运行的,我仍然看不到性能有任何改进。请在下面提出任何建议以提高性能?
服务A.java
@Autowired
ServiceB serviceb;
public List<String> getNames(List<Item> items) {
List<CompletableFuture<String>> list = new ArrayList<>();
List<String> returnList = new ArrayList<>();
for( Item item: items) {
CompletableFuture<String> getItemName = serviceb.doProcess(item);
list.add(getItemName):
}
for( CompletableFuture name : list) {
returnList.add(name.get());
}
return returnList;
}
服务B.java
Class ServiceB {
@Async
Public CompletableFuture<String> doProcess(Item item)
{
//do process
}
解决方案
您可以调用allOf来等待所有结果。这将等待所有 CompletableFuture 完成。
List<String> returnList = new ArrayList<>(items.size());
CompletableFuture<String>[] tasks = items.stream()
.map(value-> serviceb.doProcess(value).thenApply(returnList::add))
.toArray(CompletableFuture[]::new);
// wait for all tasks to finish
CompletableFuture.allOf(tasks).get(50, TimeUnit.SECONDS);
// return the results
return returnList;
第二种解决方案是使用响应式方法,例如发布者/订阅者模式(Spring WebFlux或JavaRx)。这样,您的应用程序将很少/没有等待操作。但这会影响您的应用程序架构。
一个建议:为了创建一个CompletableFuture
使用ExecutorService的构造函数,以保持检查线程数并控制正在运行的线程或应用程序关闭时。
推荐阅读
- javascript - ENOTCONN 与 process.stdout 和 process.stderr 的管道
- bash - CD 进入带有非法字符的目录路径,该字符存储在变量中
- java - Java Mail API 路由电子邮件而不修改 FROM 标头
- c# - 如何在代码隐藏中向按钮添加命令
- php - 使用 MySql 和 PHP 将数据分类到一个共同的日期
- php - 每 24 小时生成一个新的 .txt 文件
- file - 在 TCL/PERL 中以表格格式打印
- r - 标准化 igraph 中的边缘权重以进行绘图(边缘权重太厚)
- ios - 检测在“单元”上单击了哪个“视图”
- php - foreach 循环中的自动递增值,但它一直在进行