Как ждать, пока все представленные задачи в ExecutorService будут завершены без выключения?

Представьте, что мы просматриваем коллекцию и отправляем задачи для выполнения в фоновом режиме.

class Processor {
    public void process(Iterable<Item> items, ExecutorService executorService) {
       for (Item item : items) {               
           doStandardProcess(item);               
           if (needSpecialProcess(item)) {
               executorService.submit(createSpecialTaskFor(item));
           }
       }
    }
}

Ход программы выглядит так:

  1. получать предметы откуда-то
  2. создать процессор и обработать их
  3. отправить результат куда-нибудь

Результат зависит от фоновой обработки, поэтому на стр.3 следует дождаться завершения всех задач. Я знаю, что это может быть достигнуто путем комбинации shutdown() а также awaitTermination(), но я не хочу выключать сервис. Также есть возможность позвонить invokeAll(List tasks), но, как вы видите, задачи создаются одна за другой во время обхода.

Как я могу добиться ожидания завершения с данными ограничениями?

PS Если было неясно, другое ограничение - запускать фоновые задачи параллельно с обходом элементов, потому что фоновые задачи занимают в 100 раз больше времени, чем базовая операция обработки.

2 ответа

Решение

Вы можете хранить фьючерсы:

List<Future> futures = new ArrayList<> ();
//in the for loop
futures.add(executorService.submit(createTaskFor(item)));

//after for loop + add exception handling
for (Future f : futures) f.get();
//at this point all tasks have finished
List<Callable<Foo>> toProcess = new ArrayList<>();
for (Item item : items) {
    if (needProcess(item)) {
        toProcess.add(createTaskFor(item));
    }
}
executorService.invokeAll(toProcess);
Другие вопросы по тегам