В Java8 есть лучший способ сделать это, используя CompletableFuture . Скажем, у нас есть класс, который получает идентификатор из базы данных, для простоты мы можем просто вернуть число, как показано ниже,
static class GenerateNumber implements Supplier<Integer>{
private final int number;
GenerateNumber(int number){
this.number = number;
}
@Override
public Integer get() {
try {
TimeUnit.SECONDS.sleep(1);
}catch (InterruptedException e){
e.printStackTrace();
}
return this.number;
}
}
Теперь мы можем добавить результат в параллельную коллекцию, когда будут готовы результаты каждого будущего.
Collection<Integer> results = new ConcurrentLinkedQueue<>();
int tasks = 10;
CompletableFuture<?>[] allFutures = new CompletableFuture[tasks];
for (int i = 0; i < tasks; i++) {
int temp = i;
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(()-> new GenerateNumber(temp).get(), executor);
allFutures[i] = future.thenAccept(results::add);
}
Теперь мы можем добавить обратный вызов, когда все фьючерсы готовы,
CompletableFuture.allOf(allFutures).thenAccept(c->{
System.out.println(results); // do something with result
});