Mind that the function passed to thenAccept
can be performed by an arbitrary thread, so thankfully, Java does not allow them to modify a local variable. When you change the variable to a field on the heap, the compiler would accept it, but the result would be entirely broken.
The simplest solution would be
int totalCount = 0;
for(String id: API.getIDs()) {
totalCount += OtherAPI.getCount(id).join();
}
It just waits for the availability of each value, to sum them locally. Depending on the operations encapsulated by the OtherAPI.getCount(…)
calls, this might even be the most efficient solution.
But when these operations take a significant time and can truly run in parallel, i.e. do not depend on a shared resource internally, it might be beneficial not to wait before all operations have been commenced.
You can do this like
CompletableFuture<Integer> result = CompletableFuture.completedFuture(0);
for(String id: API.getIDs()) {
result = result.thenCombine(OtherAPI.getCount(id), Integer::sum);
}
System.out.println(result.join());
Here, the loop is entirely wait-free. It will schedule the summing operation, to be done when two operations have been completed. Then, only the join
call at the end will wait for the final result. At this point, all asynchronous operations have been submitted already.