对于循环,等待所有CompletableFuture给出结果,然后将结果添加到int

问题描述

我有一个方法getCount(id)从数据库返回一个整数,作为CompletableFuture。我想遍历所有id,并获取所有id的结果,并将它们添加到一个全局int。然后我想对那个int做些事情:

int totalCount;
for (String id : API.getIDs()) {
    //OtherAPI.getCount(id) will return the CompletableFuture<Integer>
    OtherAPI.getCount(id).thenAccept(count -> totalCount += count);
}

System.out.println("" + totalCount);

这会导致错误,因为您不能在thenAccept中将一个整数添加到另一个整数中,因为它是使用者。该怎么做?

解决方法

请注意,传递给lastModifiedBy的函数可以由任意线程执行,因此非常感谢,Java不允许他们修改局部变量。当您将变量更改为堆上的字段时,编译器会接受它,但结果将完全被破坏。

最简单的解决方案是

thenAccept

它只是等待每个值的可用性,以对它们进行本地求和。根据{{​​1}}调用封装的操作,这甚至可能是最有效的解决方案。

但是,当这些操作花费大量时间并且可以真正并行运行时(即,不内部依赖共享资源),最好不要等到所有操作开始后再使用。

您可以这样做

int totalCount = 0;
for(String id: API.getIDs()) {
    totalCount += OtherAPI.getCount(id).join();
}

在这里,循环完全没有等待。它将计划求和操作,该操作将在完成两个操作后进行。然后,只有最后的OtherAPI.getCount(…)调用将等待最终结果。至此,所有异步操作已经提交。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...