title: Execute parallel tasks with RxJava and wait until the last one of them is completed
body: <p>Well, this is my first question in StackOverflow, but after several days fighting with <code>RxJava</code> I am unable to find other solution, I have tried many things by my own, digging along the documentation and other posts but I am not sure how exactly do what I need. I have tried with several combinations of <code>flatMap</code>, <code>zip</code>, <code>merge</code> and others, but always reaching to a dead end, and the closest achieved solution is the code below. I would appreciate any help or guidance.</p>
  
  <p>I need a method that, given an input list, executes parallel calls with the different inputs of the list, and do not continue the execution until all the parallel calls have finished. It is also necessary to keep the results of the different executions for later uses (<strong>EDIT</strong>: In the same thread that started the execution). </p>
  
  <pre><code>public void parallelExecution(List&lt;Integer&gt; calls) {
    List&lt;String&gt; results = new ArrayList&lt;&gt;();
    logger.debug("Starting parallel executions");
    Observable.fromIterable(calls)
        .flatMap(val -&gt; Observable.just(val).observeOn(Schedulers.io())
        .doOnNext(item -&gt; results.add(simpleAsync(item).toString())))
        .subscribe(call -&gt; logger.debug("Execution: {}", Thread.currentThread().getName()));
    logger.debug("Ending parallel executions");
    for (String x : results) {
      logger.debug("Results: {}", x);
    }
  }
  
  private Integer simpleAsync(Integer number) {
    Integer result = number * number;
    logger.info("Pre log {}: {}", Thread.currentThread().getName(), result);
    try {
      Thread.sleep(number * 500);
    } catch (Exception e) {
    }
    logger.info("Post log {}: {}", Thread.currentThread().getName(), result);
    return result;
  }
  </code></pre>
  
  <p>The problem is that this code does not "waits" for the execution of the "simpleAsync" method, it finishes the execution with no "Results" logs (there are no results yet), and after that, the "Post log" traces appear executed in different threads:</p>
  
  <pre><code>Starting parallel executions
  Ending parallel executions
  Pre log RxCachedThreadScheduler-1: 1
  Pre log RxCachedThreadScheduler-2: 4
  Pre log RxCachedThreadScheduler-3: 9
  Pre log RxCachedThreadScheduler-4: 16
  Pre log RxCachedThreadScheduler-5: 25
  Post log RxCachedThreadScheduler-1: 1
  Execution: RxCachedThreadScheduler-1
  Post log RxCachedThreadScheduler-2: 4
  Execution: RxCachedThreadScheduler-2
  Post log RxCachedThreadScheduler-3: 9
  Execution: RxCachedThreadScheduler-3
  Post log RxCachedThreadScheduler-4: 16
  Execution: RxCachedThreadScheduler-4
  Post log RxCachedThreadScheduler-5: 25
  Execution: RxCachedThreadScheduler-5
  </code></pre>
  
  <p>If I delete the "observeOn" sentence, the method waits for the completion of the calls, but they are done sequentially (in the same thread):</p>
  
  <pre><code>Starting parallel executions
  Pre log Default Executor-thread-9: 1
  Post log Default Executor-thread-9: 1
  Execution: Default Executor-thread-9
  Pre log Default Executor-thread-9: 4
  Post log Default Executor-thread-9: 4
  Execution: Default Executor-thread-9
  Pre log Default Executor-thread-9: 9
  Post log Default Executor-thread-9: 9
  Execution: Default Executor-thread-9
  Pre log Default Executor-thread-9: 16
  Post log Default Executor-thread-9: 16
  Execution: Default Executor-thread-9
  Pre log Default Executor-thread-9: 25
  Post log Default Executor-thread-9: 25
  Execution: Default Executor-thread-9
  Ending parallel executions
  Results: 1
  Results: 4
  Results: 9
  Results: 16
  Results: 25
  </code></pre>