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

Alex Lam S.L. alexlamsl at gmail.com
Thu Jul 19 11:41:56 EDT 2012


I am trying to get my application to use ForkJoinPool. Specifically, I
want it to automatically occupy all 8 CPUs even when one of the thread
is blocked by BlockingQueue.take() - below is an implementation based
on what I can understand from the javadocs:


  ForkJoinPool pool = new ForkJoinPool();
  BlockingQueue<V> queue = new LinkedBlockingQueue<>();
  Callable<V> workload = ...;

  class QueueBlocker<V> implements ForkJoinPool.ManagedBlocker {
    private V value;

    public V get() {
      return value;
    }

    public boolean block() throws InterruptedException {
      value = queue.take();
      return true;
    }

    public boolean isReleasable() {
      return value != null || (value = queue.poll()) != null;
    }
  }

  class Task<V> extends ForkJoinTask<Void> {
    private final Callable<V> callable;

    Task(Callable<V> callable) {
      this.callable = callable;
    }

    public Void getRawResult() {
      return null;
    }

    protected void setRawResultVoid value) {
    }

    protected boolean exec() {
      try {
        queue.add(callable.call());
        return true;
      } catch (Exception ex) {
        throw new RuntimeException(ex);
      }
    }
  }

  final int N = ...;

  pool.execute(new Runnable() {
    public void run() {
      for (int i = 0; i < N; i++)
        pool.execute(new Task<V>(workload));

      for (int i = 0; i < N; i++) {
        final QueueBlocker blocker = new QueueBlocker();
        ForkJoinPool.managedBlock(blocker);
        process(blocker.get());
      }
    }
  });


Now on my 8-core machine, I can see from JConsole that FJ pool have 8
threads, with one of them consistently blocking on queue.take(), thus
only leaving 7 CPUs busy.

Is this behaviour intentional? If so, what am I doing wrong here?


Thanks,
Alex.


More information about the Concurrency-interest mailing list