[concurrency-interest] ForkJoinPool.managedBlock() not spawning new thread

Alex Lam S.L. alexlamsl at gmail.com
Thu Jul 19 15:05:26 EDT 2012


On Thu, Jul 19, 2012 at 6:52 PM, Doug Lea <dl at cs.oswego.edu> wrote:
>
> It is intentional that the ManagedBlocker API not continuously
> spawn threads -- this leads to positive feedback loops that
> can lead to unbounded resource usage. This also means that
> it might not spawn a thread when you might think it should.
>
> See discussions about CountedCompleters on this list for a
> generally more well-behaved approach to tasks that may block.
>
> Additionally, or alternatively, you can pad the pool size to a
> value that better estimates actual CPU-intensive load. In general,
> work-stealing has the property that as you use more threads than
> CPU cores, performance only slowly degrades due to more context switching.
> So, if you can make estimates are not grossly wrong, this may
> lead to better average utilization and throughput.

Thank you very much for the detailed explanation - CountedCompleters
doesn't quite match my usage pattern in this case, at least not I can
think of at the moment.

For the record, I went with the following approach instead:

  class QueueBlocker<V> implements ForkJoinPool.ManagedBlocker {
    ...

    public boolean block() throws InterruptedException {
      if (Task.steal()) {
        return false;
      } else {
        value = queue.take();
        return true;
      }
    }
  }

  class Task<V> extends ForkJoinTask<Void> {
    ...

    public static boolean steal() {
      final ForkJoinTask<?> task = ForkJoinTask.pollTask();
      if (task == null) {
        return false;
      } else {
        task.invoke();
        return true;
      }
    }
  }

And now my program is running at 100% CPU, i.e. I'm struggling to type
this email with GMail interface!


Alex.


More information about the Concurrency-interest mailing list