When my application launches, a executor service (using Executors.newFixedThreadPool(maxThreadNum) in java.util.concurrent) object is created. When requests come, the executor service will creates threads to handle them.
Because it takes time to create threads at run time, I want to make threads available when launching application, so that when requests come, it would take less time to process.
What I did is following:
executorService = Executors.newFixedThreadPool(200);
for (int i=0; i<200; i++) {
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println("Start thread in pool " );
}
});
}
It will creates 200 threads in the executorService pool when application launches.
Just wonder is this a correct way of creating threads when application starts? Or is there a better way of doing it?
If you can use a ThreadPoolExecutor
directly rather than an ExecutorService
from Executors
1, then there's perhaps a more standard/supported way to start all the core threads immediately.
int nThreads = 200;
ThreadPoolExecutor executor = new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
executor.prestartAllCoreThreads();
The above uses prestartAllCoreThreads()
.
Note that, currently, the implementation of Executors.newFixedThreadPool(int)
creates a ThreadPoolExecutor
in the exact same manner as above. This means you could technically cast the ExecutorService
returned by the factory method to a ThreadPoolExecutor
. There's nothing in the documentation that guarantees it will be a ThreadPoolExecutor
, however.
1. ThreadPoolExecutor
implements ExecutorService
but provides more functionality. Also, many of the factory methods in Executors
either returns a ThreadPoolExecutor
directly or a wrapper that delegates to one. Some, like newWorkStealingPool
, use the ForkJoinPool
. Again, the return types of these factory methods are implementation details so don't rely too much on it.