How to wait until all submitted tasks in ExecutorService are completed without shutdown?

556 views Asked by At

Imagine we traverse a collection and submit tasks to be run in background

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

Program flow looks like:

  1. receive items from somewhere
  2. create Processor and process them
  3. send the result to somewhere

Result depends on the background processing, so p.3 should wait until all tasks will be completed. I know it can be achieved by the combination of shutdown() and awaitTermination(), but I do not want to shutdown the service. Also there is a possibility to call invokeAll(List tasks), but as you see, tasks are created one by one during traverse.

How can I achieve waiting for completion with given restrictions?

P.S. If it was not clear, another restriction is to run background tasks in parallel with items traversal, because background tasks takes x100 more time than basic processing operation.

2

There are 2 answers

1
assylias On BEST ANSWER

You can store the futures:

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
7
JB Nizet On
List<Callable<Foo>> toProcess = new ArrayList<>();
for (Item item : items) {
    if (needProcess(item)) {
        toProcess.add(createTaskFor(item));
    }
}
executorService.invokeAll(toProcess);