Reputation: 1014
I am facing a strange situation where I have a thread pool with maxPoolSize as 100 and queue size as 30 and corePoolSize as 50. After application is restarted in some time I can see RejectedExecution errors in logs which state that even though threads are available , task was rejected.
org.springframework.core.task.TaskRejectedException: Executor [java.util.concurrent.ThreadPoolExecutor@593a81ea[Running, pool size = 100, active threads = 3, queued tasks = 17, completed tasks = 57463]]
I took thread dump many times and found that threads of this pool are doing Timed_Waiting. Above log is correct that only 3 are runnable as per dump also but I am not able to understand why rest of the 97 threads are not available to the system. Below is the thread dump which is common for 97 threads :
YYYThreadPoolExecutor-100" #6414 prio=5 os_prio=0 tid=0x00007f0830dce800 nid=0x3a39 waiting on condition [0x00007f064b6b5000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00007f0a32b21088> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
System is a 16-core box with 100 GB RAM. Current cpu utilisation is just 103% for 16 cores and RAM utilisation is <15GB.
Even if I increase thread pool size to 500 also , same situation arrives with a delay.
Has anybody faced this situation before? Thanks in advance.
Upvotes: 4
Views: 5553
Reputation: 38910
Refer to oracle documentation about ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
Creates a new ThreadPoolExecutor with the given initial parameters and default thread factory.
Parameters:
corePoolSize
- the number of threads to keep in the pool, even if they are idle, unless allowCoreThreadTimeOut is set
maximumPoolSize
- the maximum number of threads to allow in the pool
keepAliveTime
- when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.
unit
- the time unit for the keepAliveTime argument
workQueue
- the queue to use for holding tasks before they are executed. This queue will hold only the Runnable tasks submitted by the execute method.
handler
- the handler to use when execution is blocked because the thread bounds and queue capacities are reached
From the details you have provided, you have not reached Thread pool bounds due to huge number but you might have reached queue capacity.
You don't need high number for number of threads. Instead you can increase queue capacity.
Generally queue size will be configured higher value to number thread pool size. maximumPoolSize
can be configured to number of CPU cores in your machine : Runtime.getRuntime().availableProcessors()
Upvotes: 4