title: ForkJoinPool parallelism=1 deadlock
body: <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>