I want to use a common thread pool that can be used throughout my application wherever I want. Shall I create a static Executor service in the main class. Then use it wherever needed? Currently I have this in my main class(MyMainApplication.java)
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
public static final ThreadPoolExecutor getExecutor(int corePoolSize, int maxPoolSize, int keepAlive) {
return ThreadPools.getExecutor(corePoolSize, maxPoolSize, keepAlive);
}
My threadpool class:
@Component
public class ThreadPools {
private static final int DEFAULT_CORE_POOL_SIZE = 5;
private static final int DEFAULT_MAX_POOL_SIZE = 10;
private static final int DEFAULT_KEEP_ALIVE_MS = 240;
private static int corePoolSize = DEFAULT_CORE_POOL_SIZE;
private static int maxPoolSize = DEFAULT_MAX_POOL_SIZE;
private static int poolKeepAliveInMillis = DEFAULT_KEEP_ALIVE_MS;
public static ThreadPoolExecutor getExecutor(int cpSize, int maxSize, int msTime) {
if (cpSize != 0) {
setCorePoolSize(cpSize);
}
if (maxSize != 0) {
setMaxPoolSize(maxSize);
}
if (msTime != 0) {
setKeepAlive(msTime);
}
return new ThreadPoolExecutor(corePoolSize, maxPoolSize, poolKeepAliveInMillis, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(corePoolSize));
}
public static void setCorePoolSize(int size) {
ThreadPools.corePoolSize = size;
}
public static void setMaxPoolSize(int size) {
ThreadPools.maxPoolSize = size;
}
public static void setKeepAlive(int time) {
ThreadPools.poolKeepAliveInMillis = time;
}
}
And in my implementation class(GetDetails.java), I am getting the executor the following way.
public void getDetails()
{
int corePoolSize=25;
int maxPoolSize=50;
int KeepAliveTimeMs=1000;
ExecutorService executor = MyMainApplication.getExecutor(corePoolSize,
maxPoolSize, keepAlive);
..........
..........
executor.execute(runnableTask);
}
My concern is for each call to the getDetails(), will it create a new executor service with a new set of pool. so for example in production environment. if there are about 100 requests for getDetails() , will it result in creating 100 executor service with each having a their own set of the threadpool which is 100 * (25 corePoolSize, 50 maxPoolSize, 1000 keepTimeAlive). or will all the request use a common executor service with a common/same threadpool which is (25 corePoolSize, 50 maxPoolSize, 1000 keepTimeAlive). To achieve this I have made the getExecutor() in main as static. Am I doing it correctly?
You’re right to be concerned, this code will create a new threadpool every time you call getDetails. Eventually with enough calls to it you’ll run out of threads.
You could save the ExecutorService in a static variable and retrieve the saved reference instead of creating a new one every time. Alternatively you could use dependency injection and let the DI framework inject it where it’s needed.
Creating threads is expensive, while the pool can re-use existing threads, which improves the performance.
Creating a thread pool for every request is violation of it's design:
Thread pools address two different problems:
they usually provide improved performance when executing large numbers of asynchronous tasks, due to reduced per-task invocation overhead,
and they provide a means of bounding and managing the resources, including threads, consumed when executing a collection of tasks.
So it's better to make a singlton thread pool and use it everywhere.
If you do decide to create a thread pool for every request, make sure to shutdown it after all tasks finish, otherwise the pool will not be garbage collected, which leads to OutOfMemory eventually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With