It seems your problem is with changing the ForkJoinPool code between the JDK 8u20 and 8u45.
At u20, ForkJoin threads were always alive for at least 200 milliseconds (see ForkJoinPool.FAST_IDLE_TIMEOUT) before being restored.
In u45, as soon as ForkJoinPool has reached its target parallelism plus 2 additional threads, the threads will die as soon as they run out of work, without waiting for the wait. You can see this change in the awaitWork method in ForkJoinPool.java (line 1810):
int t = (short)(c >>> TC_SHIFT); // shrink excess spares if (t > 2 && U.compareAndSwapLong(this, CTL, c, prevctl)) return false;
Your program uses Phasers tasks to create additional workers. Each task gives rise to a new compensating employee, who must choose the next task.
However, as soon as you reach the goal of parallelism + 2, the compensating worker will die immediately, without waiting, and is not able to pick up the task that will be sent immediately after that.
Hope this helps.
source share