It is as simple as :
List<CompletableFuture<ResultSetType>> futures = new ArrayList<>();
while (resultSet.getResultCount() < pageSize) {
CompletableFuture<ResultSetType> completableFutureOfResultSetType =
CompletableFuture.supplyAsync(
() -> this.serveiTerritorialClientRepository.getOid("2.16.724.4.400", pageNumber, pageSize)
);
futures.add(completableFutureOfResultSetType);
pageNumber++;
}
CompletableFuture<Void> all = CompletableFuture.allOf(futures.toArray(new CompletableFuture<ResultSetType>[0]));
The problem is that all
is a CompletableFuture<Void>
, so you would then need to join
each of them to get the resultSet
:
futures.stream().map(CompletableFuture::join).collect(Collectors.toList());
The result of the above is a List of your resultSet. Mind that even if you called join
, there is no joining per-se, as it already happened because of CompletableFuture::allOf
.
Then, another problem that might arise, is the fact that some of the futures you supply to allOff
might fail. As such you will need to filter the ones that have failed and retry for them? It depends on your usage. If you want to fail if at least one failed, you need to inspect: all.isCompletedExceptionally
. The documentation of allOf
mentions that if alt least one failed, all.isCompletedExceptionally
will report failed too.
As to how many features you need, it depends.
In the example that you provide, you have no pool defined for supplyAsync
, as such - you might get a lot of threads involved. This Q&A explains why. In general it is highly recommended to provide a pool for your actions (supplyAsync
has an overloaded method that takes such an argument). In that case, it does not even matter how many futures you would be creating - as the pool threads would be responsible to schedule them. And the answer to how many you would need - is impossible without measuring. Usually (we have observed that in our usages), a few threads (2-4) is more then enough.