title: Usage of ForkJoinTask.getSurplusQueuedTaskCount()
body: <p><a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/RecursiveAction.html" rel="nofollow">Java doc of RecursiveAction</a> mentions:</p>
  
  <blockquote>
    <p>The following example illustrates some refinements and idioms that may lead to better performance: RecursiveActions need not be fully recursive, so long as they maintain the basic divide-and-conquer approach. Here is a class that sums the squares of each element of a double array, by subdividing out only the right-hand-sides of repeated divisions by two, and keeping track of them with a chain of next references. <strong>It uses a dynamic threshold based on method getSurplusQueuedTaskCount</strong>, but counterbalances potential excess partitioning by directly performing leaf actions on unstolen tasks rather than further subdividing.</p>
  </blockquote>
  
  <p>The related code:</p>
  
  <pre><code>protected void compute() {
   int l = lo;
   int h = hi;
   Applyer right = null;
   while (h - l &gt; 1 &amp;&amp; getSurplusQueuedTaskCount() &lt;= 3) {
      int mid = (l + h) &gt;&gt;&gt; 1;
      right = new Applyer(array, mid, h, right);
      right.fork();
      h = mid;
   }
   double sum = atLeaf(l, h);
   while (right != null) {
      if (right.tryUnfork()) // directly calculate if not stolen
        sum += right.atLeaf(right.lo, right.hi);
      else {
        right.join();
        sum += right.result;
      }
      right = right.next;
    }
   result = sum;
  }
  </code></pre>
  
  <p>I just wonder the reasoning of <code>getSurplusQueuedTaskCount() &lt;= 3</code>.</p>
  
  <p><a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ForkJoinTask.html#getSurplusQueuedTaskCount%28%29" rel="nofollow">Java doc of ForkJoinTask.getSurplusQueuedTaskCount()</a> mentions:</p>
  
  <blockquote>
    <p>Returns an estimate of how many more locally queued tasks are held by the current worker thread than there are other worker threads that might steal them. This value may be useful for heuristic decisions about whether to fork other tasks. In many usages of ForkJoinTasks, at steady state, each worker should aim to maintain a small constant surplus (for example, 3) of tasks, and <strong>to process computations locally if this threshold is exceeded</strong>.</p>
  </blockquote>
  
  <p>Again, why we have to <code>process computations locally if this threshold is exceeded</code>?</p>
  
  <p>My guess:</p>
  
  <p><code>getSurplusQueuedTaskCount()</code> = number of <code>locally queued tasks</code> - number of <code>other worker threads that might steal them (locally queued tasks)</code></p>
  
  <p><code>getSurplusQueuedTaskCount() &gt; 3</code> means <code>locally queued tasks</code> outnumber <code>other worker threads</code>. Thus, <code>other worker threads</code> are already so busy that they won't be able to steal any newly created tasks. Thus, the current thread should perform the calculation instead of subdividing calculation (i.e. creating new task).</p>
  
  <p>Is my guess correct?</p>