Note that there are some explanatory texts on larger screens.

plurals
  1. POForkJoinPool parallelism=1 deadlock
    primarykey
    data
    text
    <p>I'm using the jsr166y ForkJoinPool to distribute computational tasks amongst threads. But I clearly must be doing something wrong.</p> <p>My tasks seem to work flawlessly if I create the ForkJoinPool with parallelism > 1 (the default is Runtime.availableProcessors(); I've been running with 2-8 threads). But if I create the ForkJoinPool with parallelism = 1, I see deadlocks after an unpredictable number of iterations.</p> <p>Yes - setting parallelism = 1 is a strange practice. In this case, I'm profiling a parallel algorithm as thread-count increases, and I want to compare the parallel version, run with to a single thread, to a baseline serial implementation, so as to accurately ascertain the overhead of the parallel implementation.</p> <p>Below is a simple example that illustrates the issue I'm seeing. The 'task' is a dummy iteration over a fixed array, divided recursively into 16 subtasks. </p> <p>If run with THREADS = 2 (or more), it runs reliably to completion, but if run with THREADS = 1, it invariably deadlocks. After an unpredictable number of iterations, the main loop hangs in ForkJoinPool.invoke(), waiting on task.join(), and the worker thread exits.</p> <p>I'm running with JDK 1.6.0_21 and 1.6.0_22 under Linux, and using a version of jsr166y downloaded a few days ago from Doug Lea's website (<a href="http://gee.cs.oswego.edu/dl/concurrency-interest/index.html" rel="noreferrer">http://gee.cs.oswego.edu/dl/concurrency-interest/index.html</a>)</p> <p>Any suggestions for what I'm missing? Many thanks in advance.</p> <pre><code>package concurrent; import jsr166y.ForkJoinPool; import jsr166y.RecursiveAction; public class TestFjDeadlock { private final static int[] intArray = new int[256 * 1024]; private final static float[] floatArray = new float[256 * 1024]; private final static int THREADS = 1; private final static int TASKS = 16; private final static int ITERATIONS = 10000; public static void main(String[] args) { // Initialize the array for (int i = 0; i &lt; intArray.length; i++) { intArray[i] = i; } ForkJoinPool pool = new ForkJoinPool(THREADS); // Run through ITERATIONS loops, subdividing the iteration into TASKS F-J subtasks for (int i = 0; i &lt; ITERATIONS; i++) { pool.invoke(new RecursiveIterate(0, intArray.length)); } pool.shutdown(); } private static class RecursiveIterate extends RecursiveAction { final int start; final int end; public RecursiveIterate(final int start, final int end) { this.start = start; this.end = end; } @Override protected void compute() { if ((end - start) &lt;= (intArray.length / TASKS)) { // We've reached the subdivision limit - iterate over the arrays for (int i = start; i &lt; end; i += 3) { floatArray[i] += i + intArray[i]; } } else { // Subdivide and start new tasks final int mid = (start + end) &gt;&gt;&gt; 1; invokeAll(new RecursiveIterate(start, mid), new RecursiveIterate(mid, end)); } } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload