[concurrency-interest] ForkJoinExecutor.invoke and ForkJoinTask.invoke

Doug Lea dl at cs.oswego.edu
Thu Dec 13 07:32:03 EST 2007

Mark Thornton wrote:
> If you call ForkJoinExecutor.invoke from within a task being run by that 
> executor should it behave as ForkJoinTask.invoke?
> The current behaviour is that it blocks. This means that for some tasks 
> I need to provide two routes for invoking them depending on whether the 
> invoker is another task or not.

This is a good question; thanks.
Since you are the third person I've head from
who got stuck on this, it seem worth revisiting.

The issue is whether ForkJoinPool (FJP) invoke(task) should
(as now) serve as gateway between FJ and non-FJ threads,
or whether it should check to see if caller is an FJ thread
and if so act like task.invoke().
The main visible difference is that the former blocks
on join, while the latter helps on join (i.e., may execute
that or some other task until done). But there is another
difference that some people may need to rely on:
FJP.invoke schedules tasks for execution in submission order,
while plain task.invoke executes whenever it wants to
(which turns out to always be  "immediately").

So, special-casing FJP.invoke on the basis of caller would
eliminate the ability for an FJ task to submit a new poolwide
task that would be executed when one or more worker threads
don't have existing (sub)tasks to execute. I'd still like
to support a way to do this. But perhaps it would be less
error-prone for FJP.invoke(task) to act like task.invoke() if
caller is an FJ thread, and to have another method, say
ForkJoinTask.invokeLater(task) that schedules for poolwide

Further thoughts and suggestions would be welcome.


More information about the Concurrency-interest mailing list