[concurrency-interest] ForkJoinPool not designed for nested Java 8streams.parallel().forEach( ... )

Christian Fries email at christian-fries.de
Mon May 5 17:37:24 EDT 2014


Hi Aleksey.

I can confirm that the use of your ForkJoinSemaphore fixes the deadlock situation. Thank you!

Note: I believe it should be
	        public boolean isReleasable() { return false; }
otherwise we are not blocking, hence never acquiring, 

But your code (then) works!

My code linked at 
	http://svn.finmath.net/finmath%20experiments/trunk/src/net/finmath/experiments/concurrency/ForkJoinPoolTest.java
only deadlocks with isUseSemaphore = true. But note that the deadlock vanishes if isWrappedInnerLoopThread = true (with the deadly Semaphore, without your ForkJoinSemaphore).

For the deadlock situation: there are 10 threads and the semaphore will block 5. The 5 others will execute the inner loop. When you check the DEADLOCK with a debugger then you find that 5 threads are blocked at the semaphore but the 5 others are blocked at the awaitJoin of an inner task, i.e. the inner foreach:
IntStream.range(0,numberOfTasksInInnerLoop).parallel().forEach
Why are we blocking at the awaitJoin of a task of the inner loop? That was puzzling.

Thanks again for the hint to ForkJoinPool.managedBlock - that was very valuable.

Best
Christian


Am 05.05.2014 um 23:04 schrieb Aleksey Shipilev <aleksey.shipilev at oracle.com>:

> On 05/06/2014 12:40 AM, Christian Fries wrote:
>> It appears to me as if nested Java 8 parallel streams will create a
>> very subtle „implicit coupling“ between the tasks submitted to the
>> common pool, because tasks of an inner loop are joined with tasks on
>> an outer loop.
> 
> What coupling are you talking about now? In my mental model, starting
> the parallel() computation from the parallel() computation is "just"
> invoking the FJTask from the already executing one, and that is just
> forking-joining on a new task. Joining on inner FJTask will assist
> executing it. Which means that FJThreads executing the outer loop will
> assist executing the inner loop if they are "joining" on inner loop
> computations.
> 
>> So maybe the problem is to have a common FJP at all?
>> 
>> I still have the impression that the line ((t =
>> Thread.currentThread()) instanceof ForkJoinWorkerThread) is not
>> correct in the case of a nested loop.
> 
> Why? It checks if we are within the FJP and may proceed to awaitJoin to
> *help* other tasks.
> 
> -Aleksey.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20140505/4040d39b/attachment.html>


More information about the Concurrency-interest mailing list