4

Executors.newWorkStealingPool() allows creating a limited concurrency pool with target parallelism. Under the hood, it seems to create a new ForkJoinPool with default worker creation factory which is defined here.

This factory seems to create new threads until desired concurrency is reached. Why does this pool not allow using a subset of threads from an existing pool to support limited concurrency while still avoiding creation of new threads everytime? I would assume creation of threads is expensive in Java.

Related: Use only a subset of threads in an ExecutorService

Rohit Banga
  • 18,458
  • 31
  • 113
  • 191

1 Answers1

4

Why does this pool not allow using a subset of threads from an existing pool to support limited concurrency while still avoiding creation of new threads everytime?

The Thread and ThreadFactory APIs don't allow you to recycle an arbitrary Thread object. The problem is that the ThreadFactory::newThread requires an implementation to return a thread with a given Runnable but the Thread API only allows the Runnable to be set by the Thread constructor.

  • Fixing this in Thread would break the model. (What does it mean to replace the Runnable of a thread that has been started.)

  • It could in theory be fixed by defining a subclass of Thread where the actual run() method runs user-supplied Runnable in a loop. But it gets complicated .... and you would only be able to recycle instance of that subclass ... not arbitrary threads.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • But isn't it true that threads created by Executors.newFixedThreadPool() etc. and thread pools used by various applications recycle threads? Even within ForkJoinPool if several tasks are submitted to the same pool and the existing thread outlives the execution of that specific runnable / Callable effectively recycling the thread. – Rohit Banga Nov 24 '17 at 07:59
  • 1
    Yes. But that (the recyling) is done by the `Runnable`. So, for example, a thread pool will instantiate new threads with a `Runnable` whose `run()` method returns the thread to the pool and waits for more work. Look at the APIs ... and the implementation code. – Stephen C Nov 24 '17 at 08:06
  • Ok. Is it correct to say that the reason is that the WorkQueue in the ForkJoinPool that injects task in the ForkJoinPool is coupled with the pool itself so we cannot create an arbitrary work queue with defined concurrency level and force fork join pool to use it? I feel like that is a missing feature, since I believe creating threads on Java is expensive https://stackoverflow.com/a/5483105/161628 – Rohit Banga Nov 24 '17 at 08:12
  • 1
    @RohitBanga: *none* of the JRE provided executors supports using threads of another executor. That’s not `ForkJoinPool` specific. The logic behind this is simple. If you tell the JRE to create a new thread pool, you will get a new thread pool. – Holger Nov 24 '17 at 14:18
  • 1
    @RohitBanga - *"I feel like that is a missing feature ..."* - Tell it to the designers. But think you are wasting your time unless you have a concrete design proposal that is 1) clean, and 2) backwards compatible with the current design. – Stephen C Nov 24 '17 at 14:22