[concurrency-interest] ForkJoinPool sometimes blocks an outer on a nested task (Java 9 and later)
lukas.rytz at lightbend.com
Thu Oct 1 08:14:47 EDT 2020
I'm new on this list and not a concurrency expert. I'm the lead of the
Scala team at Lightbend which maintains the compiler and standard library.
We recently had a bug report of a parallel collections operation being
blocked on the termination of a Future started within the operation body. I
managed to reproduce the behavior in a fairly small Java-only example using
ForkJoinPool, the code is here:
The code starts a task, which forks two subtasks and joins them, the
subtasks recursively do the same, until some depth. Each one of these tasks
is fast (2ms). Additionally, the first task creates a subtask that is slow
(200ms), but does *not* join on it. On Java 8, each top-level task returns
quickly. On Java 9 and later, from time to time the top-level task gets
blocked on the slow subtask and only returns after 200+ ms. I tested Java
1.8.0_261-b12 for 8, and 9+181, 11.0.6+10, 14.0.1+7, 15+36-1562.
The issue is more common when the pool's parallelism is lower. With a
parallelism of 4, I did a 10 seconds flight recording, and there is a
pretty obvious difference: on Java 8 there were > 20 pool threads, while on
Java 11 there were only 5 of them. The screenshots show the long wait
periods on Java 11:
I did a short search of this list's archive and found one thread that looks
somewhat related, though if I understand correctly that older discussion is
about tasks that involve some sort of blocking, which is not the case in
I'd like to know whether the Java 9+ behavior is a bug or within spec - I
hope it's an appropriate question for this list.
> The pool attempts to maintain enough active (or available) threads by
dynamically adding, suspending, or resuming internal worker threads, even
if some tasks are stalled waiting to join others
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Concurrency-interest