IAmYourFaja
IAmYourFaja

Reputation: 56944

How to wait for all callables to finish executing before proceeding?

I have the following code hashed out:

public class MyCallable implements Callable<Long> {
    @Override
    public Long call() throws Exception {
        // Do stuff...
    }
}

public class MyController {
    private ExecutorService executor = Executos.newCachedTreadPool();

    public Long concurrentDoStuff() {
        List<MyCallable> workers = makeWorkers();

        List<Long> allResults = new ArrayList<Long>();
        for(MyCallable worker : workers) {
            Future<Long> workerResults = executor.submit(worker);

            try {
                allResults.add(workerResults.get());
            } catch(InterruptedException ie) {
                // Handle...
            } catch(ExecutionException ee) {
                // Handle...
            }
        }

        // Question: how do I pause here and wait for all workers to finish?
    }
}

After the for-loop, I want to wait for all workers to finish before proceeding any further. What's the best/safest/most-efficient way to do this? Thanks in advance!

Upvotes: 5

Views: 3760

Answers (4)

K Adithyan
K Adithyan

Reputation: 396

There is a handy method.

ExecutorService.invokeAll(List<Callable> callables);

It will return List<Future> objects so that you can get the returned objects of all your individual call() methods.

You can get the instance of ExecutorService by calling Executors.new....()

Upvotes: 1

Duncan Jones
Duncan Jones

Reputation: 69409

You can call:

executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE , TimeUnit.NANOSECONDS);

This will wait (almost) indefinitely for the tasks to complete.

Upvotes: 4

Alex
Alex

Reputation: 13961

Use a CountDownLatch.

  • Initialize it with the number of workers
  • Pass a reference to the latch in the worker constructor
  • When the worker is done, call countDown
  • Call await in the main thread and it will block until the workers are done.

This is a more general-purpose solution than using methods on the executor service.

Upvotes: 5

Ralf H
Ralf H

Reputation: 1474

You must shut the Executor down with shutDown and then wait until all jobs have been processed with awaitTermination.

Upvotes: 4

Related Questions