title: What would be the best approach to use CompletableFuture while running a stream of asynchronous tasks?
body: <p>I have a spring component EventSvcFacade which HAS-A list of three EventValidationSvc implementation class instances. Each of these classes implements the method <code>boolean validate(T request)</code>, takes the same input but calls different APIs on the input, processes the result, and returns a boolean. This flow is thus designed for concurrent invocation. I have figured out two approaches to return a list of Boolean from the stream of tasks. Can anyone suggest, on what factors one approach is better than the other, or is there any other better approach?</p>
  
  <pre><code>@Component
  public class EventSvcFacade {
  
      @Autowired
      private List&lt;EventValidationSvc&lt;EventRequest&gt;&gt; validationSvcs;
  
      @Autowired
      private ThreadPoolExecutor threadPoolExecutor;
  
      public List&lt;Boolean&gt; firstApproach(){
        final List&lt;CompletableFuture&lt;Boolean&gt;&gt; futures = validationSvcs.stream().map(service -&gt; 
              CompletableFuture.supplyAsync(() -&gt; service.validate(eventRequest), threadPoolExecutor))
              .collect(Collectors.toList());                                                                                      
        final List&lt;Boolean&gt; values = futures.stream().map(CompletableFuture :: 
              join).collect(Collectors.toList());
        return values;
      }
  
      public List&lt;Boolean&gt; secondApproach() {
        final List&lt;Boolean&gt; values = Collections.synchronizedList(new ArrayList&lt;&gt;());
        final CountDownLatch countDownLatch = new CountDownLatch(validationSvcs.size());
        validationSvcs.stream().forEach(service -&gt; CompletableFuture.runAsync(() -&gt; {         
              try{
               values.add(service.validate(eventRequest));
              }finally{
               countDownLatch.countDown();
              }
            }, threadPoolExecutor)
        );
        countDownLatch.await();
        return values;
     }
  }
  </code></pre>