title: Java ForkJoinPool with non-recursive tasks, does work-stealing work?
body: <p>I want to submit <code>Runnable</code> tasks into ForkJoinPool via a method:</p>
  
  <pre><code>forkJoinPool.submit(Runnable task)
  </code></pre>
  
  <p>Note, I use JDK 7.</p>
  
  <p>Under the hood, they are transformed into ForkJoinTask objects. 
  I know that ForkJoinPool is efficient when a task is split into smaller ones recursively.</p>
  
  <p><strong>Question:</strong></p>
  
  <p>Does work-stealing still work in the ForkJoinPool if there is no recursion?</p>
  
  <p>Is it worth it in this case?</p>
  
  <p><strong>Update 1:</strong>
  Tasks are small and can be unbalanced. Even for strictly equal tasks, such things like context switching, thread scheduling, parking, pages misses etc. get in the way leading to the <strong>imbalance</strong>.</p>
  
  <p><strong>Update 2:</strong>
  Doug Lea wrote in the <a href="http://cs.oswego.edu/pipermail/concurrency-interest/2012-January/008987.html" rel="noreferrer">Concurrency JSR-166 Interest</a> group, by giving a hint on this:</p>
  
  <blockquote>
    <p>This also greatly improves throughput when all tasks are async and
    submitted to the pool rather than forked, which becomes a reasonable
    way to structure actor frameworks, as well as many plain services that
    you might otherwise use ThreadPoolExecutor for.</p>
  </blockquote>
  
  <p>I presume, when it comes to reasonably small CPU-bound tasks, ForkJoinPool is the way to go, thanks to this optimization. The main point is that these tasks are already small and needn't a recursive decomposition. <strong>Work-stealing</strong> works, regardless whether it is a big or small task - tasks can be grabbed by another free worker from the Deque's tail of a busy worker.</p>
  
  <p><strong>Update 3:</strong>
  <a href="http://letitcrash.com/post/17607272336/scalability-of-fork-join-pool" rel="noreferrer">Scalability of ForkJoinPool</a> - benchmarking by Akka team of ping-pong shows great results.</p>
  
  <p>Despite this, to apply ForkJoinPool more efficiently requires performance tuning.</p>