As far as I understand, a ForkJoinPool uses the 'Last-in-First-Out principle (LiFo)'. Perhaps the best explanation I could find is this link. However, the invokeall()
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?
Wouldn't this lead to fewer 'compensation threads' ? I am thinking of rewriting my code to submit tasks, rather than using invokeall()
, and join them on the LiFo basis because of this. See also:
ForkJoinPool stalls during invokeAll/join
ForkJoinPool seems to waste a thread
EDIT: 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.
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> 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<Future<T>> futures = new ArrayList<>(tasks.size());
try {
for (Callable<T> t : tasks) {
ForkJoinTask<T> f = new ForkJoinTask.AdaptedCallable<T>(t);
futures.add(f);
externalSubmit(f);
}
for (int i = 0, size = futures.size(); i < size; i++)
((ForkJoinTask<?>)futures.get(i)).quietlyJoin();
return futures;
} catch (Throwable t) {
for (int i = 0, size = futures.size(); i < size; i++)
futures.get(i).cancel(false);
throw t;
}
}