Akka Dispatcher Thread creation

I have been working on Akka Actor model. I have an usecase where more than 1000 actors will be in active and I have to process those actors. I thought of controlling the thread count through configuration defined in the application.conf.

But no. of dispatcher thread created in my application makes me helpless in tuning the dispatcher configuration. Each time when I restart my application, I see different number of dispatcher threads created (I have checked this via Thread dump each time after starting the application).

Even thread count is not equal to the one which I defined in parallelism-min. Due to this low thread count, my application is processing very slowly. On checking the no. of core in my machine through the below code:

Runtime.getRuntime().availableProcessors();

It displays 40. But the no. of dispatcher thread count created is less than 300 even I configured parallelism as 500.

Following is my application.conf file:

consumer-dispatcher {
  type = "Dispatcher"

  executor = "fork-join-executor"

  fork-join-executor {
    parallelism-min = 500
    parallelism-factor = 20.0
    parallelism-max = 1000
  }

  shutdown-timeout = 1s

  throughput = 1
}

May I know on what basis akka will be creating dispatcher threads internally and how I can increase my dispatcher thread count to increase parallel processing of actors?

First let me answer the question directly.

A fork-join-executor will be backed by a java.util.concurrent.forkJoinPool pool with its parallelism set to the implied parallelism from the dispatcher config. (parallelism-factor * processors, but no larger than max or less than min). So, in your case, 800.

And while I’m no expert on the implementation of the ForkJoinPool the source for the Java implementation of ForkJoinPool says “All worker thread creation is on-demand, triggered by task submissions, replacement of terminated workers, and/or compensation for blocked workers.” and it has methods like getActiveThreads(), so it’s clear that ForkJoinPool doesn’t just naively create a giant pool of workers.

In other words, what you are seeing is expected: it’s only going to create threads as they are needed. If you really must have a gigantic pool of worker threads you could create a thread-pool-executor with a fixed-pool-size of 800. This would give you the implementation you are looking for.

But, before you do so, I think you are entirely missing the point of actors and Akka. One of the reasons that people like actors is that they are much more lightweight than threads and can give you a lot more concurrency than a thread. (Also note that concurrency != parallelism as noted in the documentation on concepts.) So trying to create a pool of 800 threads to back 1000 actors is very wasteful. In the akka docs introduction it highlights “Millions of actors can be efficiently scheduled on a dozen of threads”.

I can’t tell you exactly how many threads you need without knowing your application (for example if you have blocking behavior) but the defaults (which would give you a parallelism factor of 20) is probably just fine. Benchmark to be certain, but I really don’t think you have a problem with too few threads. (The ForkJoinPool behavior you are observing seems to confirm this.)