[concurrency-interest] ForkJoinTask does not re-check task status entailing overhead

Rémi Barat rba at activeviam.com
Tue Nov 6 04:11:55 EST 2018


In one of our test we create around 260,000 ForkJoinTasks from one parent
task. The parent task sets a flag which causes every child task to cancel
itself (using super.cancel).

Please find attached a class to reproduce the test. In Java 8, this test is
instantaneous, whereas it takes around 25s on my machine with Java 11.

After investigation, it seems that this difference in duration comes from a
change in the ForkJoinPool#awaitJoin(WorkQueue, ForkJoinTask<?>, long)
function, which does not check that the task status is DONE anymore:

* in Java 8, before trying to help or removeAndExec, we check the current
task status:
for (;;) {
    if ((s = task.status) < 0)
    // else, try to help other tasks
As the task was cancelled, the function returns immediately.

* in Java 11, the check is not performed, which causes the execution of the
ForkJoinPool#tryRemoveAndExec function, which vainly browses the list of
tasks and induces the overhead.

The question is: is the check on the task status necessary, or did we do
something wrong?

Rémi Barat
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20181106/2cfee344/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: InterruptedForkJoinTasks.java
Type: text/x-java
Size: 2559 bytes
Desc: not available
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20181106/2cfee344/attachment.java>

More information about the Concurrency-interest mailing list