Просто чтобы предоставить больше альтернатив, здесь можно использовать защелки / барьеры.
Вы также можете получить частичные результаты, пока все они не завершат использование CompletionService .
Из Java Concurrency на практике:
«Если у вас есть пакет вычислений для отправки Исполнителю, и вы хотите получить их результаты, как они становятся
доступно, вы можете сохранить будущее, связанное с каждой задачей, и многократно запрашивать завершение, вызывая get с
тайм-аут нуля. Это возможно, но утомительно . К счастью, есть лучший способ : услуга завершения. "
Здесь реализация
public class TaskSubmiter {
private final ExecutorService executor;
TaskSubmiter(ExecutorService executor) { this.executor = executor; }
void doSomethingLarge(AnySourceClass source) {
final List<InterestedResult> info = doPartialAsyncProcess(source);
CompletionService<PartialResult> completionService = new ExecutorCompletionService<PartialResult>(executor);
for (final InterestedResult interestedResultItem : info)
completionService.submit(new Callable<PartialResult>() {
public PartialResult call() {
return InterestedResult.doAnOperationToGetPartialResult();
}
});
try {
for (int t = 0, n = info.size(); t < n; t++) {
Future<PartialResult> f = completionService.take();
PartialResult PartialResult = f.get();
processThisSegment(PartialResult);
}
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
catch (ExecutionException e) {
throw somethinghrowable(e.getCause());
}
}
}