title: CompletableFuture: proper way to run a list of futures, wait for result and handle exception
body: <p>I have a legacy code which have dozen database calls to populate a report, it takes noticeable amount of time which I try to reduce using <code>CompletableFuture</code>. </p>
  
  <p>I have some doubts that I do things correctly and not overuse this technology.</p>
  
  <p>My code now looks like this:</p>
  
  <ol>
  <li><p>Start asynchronous population of document sections with many database calls inside each methods</p>
  
  <pre><code>CompletableFuture section1Future = CompletableFuture.supplyAsync(() -&gt; populateSection1(arguments));
  CompletableFuture section2Future = CompletableFuture.supplyAsync(() -&gt; populateSection2(arguments));
      ...
  CompletableFuture section1oFuture = CompletableFuture.supplyAsync(() -&gt; populateSection10(arguments));
  </code></pre></li>
  <li><p>Then I'm arranging futures in specific order in <code>arrayList</code> and joining all of them to make sure that my code will run further only when all futures are finished.</p>
  
  <pre><code>List&lt;CompletableFuture&gt; futures = Arrays.asList(
              section1Future,
              section2Future, ...
              section10Future);
  
  List&lt;Object&gt; futureResults = futures.stream()
              .map(CompletableFuture::join)
              .collect(Collectors.toList());
  </code></pre></li>
  <li><p>Then I'm populating PDF document itself with its pieces</p>
  
  <pre><code>Optional.ofNullable((PdfPTable) futureResults.get(0)).ifPresent(el -&gt; populatePdfElement(document, el));
  Optional.ofNullable((PdfPTable) futureResults.get(1)).ifPresent(el -&gt; populatePdfElement(document, el));
      ...
  Optional.ofNullable((PdfPTable) futureResults.get(10)).ifPresent(el -&gt; populatePdfElement(document, el));
  </code></pre>
  
  <p>return document</p></li>
  </ol>
  
  <p>My concerns are:</p>
  
  <p>1) Is it okay to create and instantiate many Completable Futures in such way? Order them in required sequence in <code>arrayList</code>, join them to make sure that they are all finished, and then get result by casting them into specific object?</p>
  
  <p>2) Is it okay to run without specifying an executor service but to rely on common <code>ForkJoinPool</code>? However this code runs in web container, so probably in order to use JTA I need to use container provided thread pool executor via JNDI? </p>
  
  <p>3) If this code is surrounded in try-catch I should be able to catch <code>CompletionException</code> in main thread, right? Or In order to do that I should declare each features like following:</p>
  
  <pre><code>CompletableFuture.supplyAsync(() -&gt; populateSection1(arguments))
      .exceptionally (ex -&gt; {
                      throw new RuntimeException(ex.getCause());
          });
  </code></pre>
  
  <p>4) Is it possible to overuse CompletableFutures so they become a  performance bottleneck  itself? Like many futures waits one executor to start running? How to avoid that? Use container provided executor service?
  If yes, could someone please point me to some best practice on how to correctly configure executor service taking to account processors and memory amount?</p>
  
  <p>5) A memory impact. I read in parallel thread that there can be a problem with OOME as many object are created and garbage collected. Is there a best practice on how to calculate correct amount of memory required for application?</p>