title: ForkJoinPool: does invokeall() join in the wrong order?
body: <p>As far as I understand, a ForkJoinPool uses the 'Last-in-First-Out principle (LiFo)'. Perhaps the best explanation I could find is <a href="https://github.com/albertattard/java-fork-join-example//" rel="nofollow noreferrer">this link</a>.  However, the <code>invokeall()</code> method in ForkJoinPool.java seems to join  (quietlyjoin() ?) the tasks in the order where they were submitted (FiFo), see  the code below. Doesn't it make more sense to do it the other way around since all processing is LiFo? </p>
  
  <p>Wouldn't this lead to fewer 'compensation threads' ? I am thinking of rewriting my code to submit tasks, rather than using <code>invokeall()</code>, and join them on the LiFo basis because of this.  See also: </p>
  
  <p><a href="https://stackoverflow.com/questions/16894929/forkjoinpool-stalls-during-invokeall-join">ForkJoinPool stalls during invokeAll/join</a></p>
  
  <p><a href="https://stackoverflow.com/questions/9677506/forkjoinpool-seems-to-waste-a-thread">ForkJoinPool seems to waste a thread</a></p>
  
  <p><strong><em>EDIT</em></strong>: there is a difference whether a task is submitted to the external que or the deque of a worker. I am refering to the deque of the worker. I assume that invokeall() can lead to threadstalling here.</p>
  
  <pre><code>public &lt;T&gt; List&lt;Future&lt;T&gt;&gt; invokeAll(Collection&lt;? extends Callable&lt;T&gt;&gt; tasks) {
          // In previous versions of this class, this method constructed
          // a task to run ForkJoinTask.invokeAll, but now external
          // invocation of multiple tasks is at least as efficient.
          ArrayList&lt;Future&lt;T&gt;&gt; futures = new ArrayList&lt;&gt;(tasks.size());
  
          try {
              for (Callable&lt;T&gt; t : tasks) {
                  ForkJoinTask&lt;T&gt; f = new ForkJoinTask.AdaptedCallable&lt;T&gt;(t);
                  futures.add(f);
                  externalSubmit(f);
              }
              for (int i = 0, size = futures.size(); i &lt; size; i++)
                  ((ForkJoinTask&lt;?&gt;)futures.get(i)).quietlyJoin();
              return futures;
          } catch (Throwable t) {
              for (int i = 0, size = futures.size(); i &lt; size; i++)
                  futures.get(i).cancel(false);
              throw t;
          }
      }
  </code></pre>