Using the answer given by user sjlee here Impossible to make a cached thread pool with a size limit?
I'm not sure you've fully understood the answer that you linked to. It states that the only way that more than the core threads will be started is if the queue is full. So if we look at your code:
new ThreadPoolExecutor(100, // core size
10000, // max size
1000, // idle timeout
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(Integer.MAX_SIZE)); // queue with a size
This means that you will never start the 101st thread unless you really enqueue 2^31-1 tasks to the thread-pool. I don't think that you really should be starting 10,000 threads anyway but that's another issue.
If there are more than coreSize 100 * queueSize 20 tasks, the number of thread will increase until it hits max size.
I'm not sure where the number 20 comes from. In your code, the queue-size is Integer.MAX_SIZE
so you'll have to enqueue more than Integer.MAX_SIZE
before additional threads over the core size are started.
But the problem is, lets say everything's done and there are no more tasks, the number of threads would not decrease.
The number of threads will decrease down to the core-threads number. As @debaicai mentions, you can set the threadPool.allowCoreThreadTimeOut(true)
to have the core threads also timeout. As an aside, 1 second seems like a pretty low timeout number but maybe that makes sense to your application.
Next, how to make the Executor queue the extras to run later?
The extras? Well you certainly should consider limiting the size of your blocking queue to something more reasonable. You might want to take a look at my solution for growing a thread pool before enqueuing.