Waiting on a list of Future Waiting on a list of Future multithreading multithreading

Waiting on a list of Future


You can use a CompletionService to receive the futures as soon as they are ready and if one of them throws an exception cancel the processing. Something like this:

Executor executor = Executors.newFixedThreadPool(4);CompletionService<SomeResult> completionService =        new ExecutorCompletionService<SomeResult>(executor);//4 tasksfor(int i = 0; i < 4; i++) {   completionService.submit(new Callable<SomeResult>() {       public SomeResult call() {           ...           return result;       }   });}int received = 0;boolean errors = false;while(received < 4 && !errors) {      Future<SomeResult> resultFuture = completionService.take(); //blocks if none available      try {         SomeResult result = resultFuture.get();         received ++;         ... // do something with the result      }      catch(Exception e) {             //log         errors = true;      }}

I think you can further improve to cancel any still executing tasks if one of them throws an error.


If you are using Java 8 then you can do this easier with CompletableFuture and CompletableFuture.allOf, which applies the callback only after all supplied CompletableFutures are done.

// Waits for *all* futures to complete and returns a list of results.// If *any* future completes exceptionally then the resulting future will also complete exceptionally.public static <T> CompletableFuture<List<T>> all(List<CompletableFuture<T>> futures) {    CompletableFuture[] cfs = futures.toArray(new CompletableFuture[futures.size()]);    return CompletableFuture.allOf(cfs)            .thenApply(ignored -> futures.stream()                                    .map(CompletableFuture::join)                                    .collect(Collectors.toList())            );}


Use a CompletableFuture in Java 8

    // Kick of multiple, asynchronous lookups    CompletableFuture<User> page1 = gitHubLookupService.findUser("Test1");    CompletableFuture<User> page2 = gitHubLookupService.findUser("Test2");    CompletableFuture<User> page3 = gitHubLookupService.findUser("Test3");    // Wait until they are all done    CompletableFuture.allOf(page1,page2,page3).join();    logger.info("--> " + page1.get());