1

Using the answer given by user sjlee here Impossible to make a cached thread pool with a size limit?

With the code

new ThreadPoolExecutor(100, // core size
    10000, // max size
    1000, // idle timeout
    TimeUnit.MILLISECONDS,
    new LinkedBlockingQueue<Runnable>(Integer.MAX_SIZE)); // queue with a size

If there are more than coreSize 100 * queueSize 20 tasks, the number of thread will increase until it hits max size.

OK.

But the problem is, lets say everything's done and there are no more tasks, the number of threads would not decrease.

How to make the Executor reduce the number of threads to 0 when they're all idling?

Next, how to make the Executor queue the extras to run later?

theAnonymous
  • 1,701
  • 2
  • 28
  • 62
  • Read the javadoc: *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.* – JB Nizet Aug 20 '17 at 06:03
  • I want the threads to reduce to 0 when they're all idle. It is not possible to set 1 for the core size because that 1 thread will just take all the tasks. – theAnonymous Aug 20 '17 at 06:06
  • Why? The thread will sit there - not consuming any resources. Or just throw away the reference to the executor. Then everything gets garbage collected at some point. – GhostCat Aug 20 '17 at 14:03

2 Answers2

1

You can use allowCoreThreadTimeOut(true) to do that the core-thread will terminate when timeout.

dabaicai
  • 999
  • 8
  • 9
0

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.

Gray
  • 115,027
  • 24
  • 293
  • 354