mcacorner
mcacorner

Reputation: 1274

ExecutorService wait for all Future to complete

I have below code for ExecutorService.

try{
    ExecutorService executor = Executors.newFixedThreadPool(5);
    List<Callable<String>> taskList = new ArrayList<Callable<String>>(5);
    for(int i=1;i<=5;i++){
        taskList.add(new SimpleTask());
    }

    List<Future<String>> list =  executor.invokeAll(taskList);
    executor.shutdown();
    System.out.println(list.get(0).get());
    System.out.println("Exit");
}catch(Exception e){
    e.printStackTrace();
}

class SimpleTask implements Callable<String> {
    @Override
    public String call() throws Exception {     
        return new Date().toString();
    }
}

I want to know list.get(0).get() will wait for all task to complete?

Upvotes: 4

Views: 8669

Answers (2)

Sunil Kanzar
Sunil Kanzar

Reputation: 1260

Here code will not wait while execution of list.get(0).get() statement but executor.invokeAll(taskList) statement because invokeAll() method itself will wait for complication of all the threads.

To learn more Answer

Upvotes: 4

L.Spillner
L.Spillner

Reputation: 1772

No, the code as it is will not wait for every task to finish. By calling list.get(0).get() you are retrieving the very first optional call get() on it which will block the thread according to the documentation.

To wait for every callable to finish you need to iterate through the list and see if all are done. Of course you can do this by calling get() on every single one of them but then you would block your main thread the whole time. I myself prefer to being able to do stuff while i am waiting for other threads to execute.

Example using Java 8 streams:

// filter if any future is not done yet
while ( list.stream().anyMatch(i->!i.isDone()) )
{
  // Do whatever you want parallel to the evaluation of the Future objects

  // example
  System.err.println( "Not all are done yet." );
}
// process your results

// example:
String[] results = list.stream().map( Main::evalGet ).toArray(String[]::new);

Note: priavte static <T> TevalGet(Future<T> fu) is just a wrapper function to keep the lambda expression clean of exception-handling and looks similar to this:

private static <T> T evalGet( Future<T> fu )
  {
    T obj = null;
    try
    {
      obj = fu.get();
    }
    catch ( InterruptedException | ExecutionException e )
    {
      e.printStackTrace();
    }
    return obj;
  }

Upvotes: -1

Related Questions