当前位置: 首页 > 知识库问答 >
问题:

For 循环等待所有 CompletableFutures 给出结果,并将结果添加到 int

聂炜
2023-03-14

我有一个方法getCount(id),它从数据库返回一个整数,作为CompletableFuture。我想遍历所有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);

这会给出一个错误,因为您不能在Accept中将一个整数添加到另一个整数,因为它是一个消费者。怎么做?

共有1个答案

叶恩
2023-03-14

请注意,传递给 thenAccept 的函数可以由任意线程执行,因此值得庆幸的是,Java 不允许它们修改局部变量。当您将变量更改为堆上的字段时,编译器将接受它,但结果将完全中断。

最简单的解决方案是

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

它只是等待每个值的可用性,在本地对它们求和。根据< code > other API . get count(…)调用封装的操作,这甚至可能是最有效的解决方案

但是,当这些操作需要很长时间并且能够真正并行运行时,即不依赖于内部共享资源,那么在开始所有操作之前不要等待可能是有益的。

你可以这样做

CompletableFuture<Integer> result = CompletableFuture.completedFuture(0);
for(String id: API.getIDs()) {
    result = result.thenCombine(OtherAPI.getCount(id), Integer::sum);
}
System.out.println(result.join());

在这里,循环完全无需等待。它将安排求和操作,在完成两个操作后完成。然后,只有最后的加入调用将等待最终结果。此时,所有异步操作都已提交。

 类似资料:
  • 问题内容: CREATE TABLE logistics ( id int primary key, campaign VARCHAR(255), event_type VARCHAR (255), date_offered VARCHAR (255), date_ordered DATE, date_delivered DATE, date_recorded DATE, date_complet

  • 我是GraphQL的新手。我正在使用亚马逊和Itunes的API获取一本书的标题(和其他信息)。我返回的对象如下: 我可以调用Amazon和ITunes API并返回一本书的可用数据。但是,我希望能够插入EAN/ISBN数组,并从Amazon和ITunes返回所有书籍的数据。 因此,查询应该是这样的: 而回应: 我已经搜索了使用graphQLList的例子,但我不确定在哪里使用graphQLLis

  • 我正在努力实现这样的目标。这是一个虚构的例子,表达了这个意图。 我希望所有可完成的未来都能执行,并将所有结果合并为一个结果,然后返回。因此,对于下面的示例,集合allResults应该有字符串“1”、“2”、“3”,每个字符串有3次。我希望它们都并行运行,而不是串行运行。 任何关于未来我可以使用什么API来实现这一点的建议都会非常有用。

  • 问题内容: 我正在使用bluebird,方法 getAll 和 update return promises。我如何说“等到两个承诺返回,然后更新currentProduct值”?我对JS很陌生… 问题答案: 如果可以使用/,这将很简单。 或者,如果您只能使用简单的承诺,则可以遍历所有产品,并将每个承诺置于最后一个循环中。这样,仅当前一个问题解决时,它才会前进到下一个问题(即使它将首先迭代整个循环

  • 问题内容: 我正在用SSRS编写一份报告。该数据集填充有MS SQL Server的SQL查询。它使用Union All查询几个相似的表。问题是有一些信息丢失。不同的表适用于不同的工作站点,但是这些表中的任何列都没有站点名称。标识站点的唯一方法是通过表名。在“全部合并”的结果的合并列中,无法分辨出哪些行来自哪个站点。 有没有一种方法可以更改我的查询以在结果中添加一列,该列将具有与每一行相关联的工作

  • 问题内容: 我正在寻找一种方法来异步执行go中的两个函数,该函数返回不同的结果和错误,等待它们完成并打印两个结果。另外,如果一个函数返回错误,我不想等待另一个函数,只打印错误。例如,我具有以下功能: 这里https://play.golang.org/p/-8StYapmlg是我是如何实现它,但是它有太多的代码,我想。可以通过使用interface {}来简化它,但是我不想这样。我想要更简单的东西