ThreadPool will create maximum of 10 threads to process 10 requests at a time.
The default configuration is a core pool size of 1, with unlimited max pool size and unlimited queue capacity. This is roughly equivalent to Executors.
The core pool size is the number of threads that should be alive in a thread pool. The core threads are not terminated by the thread pool even if they are idle. Maximum Pool Size. This is the largest number of threads that we can create in a thread pool.
From this blog post:
Take this example. Starting thread pool size is 1, core pool size is 5, max pool size is 10 and the queue is 100.
As requests come in, threads will be created up to 5 and then tasks will be added to the queue until it reaches 100. When the queue is full new threads will be created up to
maxPoolSize
. Once all the threads are in use and the queue is full tasks will be rejected. As the queue reduces, so does the number of active threads.
IF running threads > corePoolSize & < maxPoolSize, then create a new Thread if Total task queue is full and new one is arriving.
Form doc: (If there are more than corePoolSize but less than maximumPoolSize threads running, a new thread will be created only if the queue is full.)
Now, Take a simple example,
ThreadPoolExecutor executorPool = new ThreadPoolExecutor(5, 10, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(50));
Here, 5 is the corePoolSize - means Jvm will create new thread for new task for first 5 tasks. and other tasks will be added to the queue until queue is getting full (50 tasks).
10 is the maxPoolSize - JVM can create max 10 threads. Means if there are already 5 task/thread is running and queue is full with 50 pending tasks and if one more new request/task is arriving in queue then JVM will create new thread up to 10 (total threads=previous 5 + new 5);
new ArrayBlockingQueue(50) = is a total queue size - it can queue 50 tasks in it.
once all 10 threads are running and if new task is arriving then that new task will be rejected.
Rules for creating Threads internally by SUN:
If the number of threads is less than the corePoolSize, create a new Thread to run a new task.
If the number of threads is equal (or greater than) the corePoolSize, put the task into the queue.
If the queue is full, and the number of threads is less than the maxPoolSize, create a new thread to run tasks in.
If the queue is full, and the number of threads is greater than or equal to maxPoolSize, reject the task.
Hope, This is HelpFul.. and please correct me if i'm wrong...
From the doc:
When a new task is submitted in method execute(java.lang.Runnable), and fewer than corePoolSize threads are running, a new thread is created to handle the request, even if other worker threads are idle. If there are more than corePoolSize but less than maximumPoolSize threads running, a new thread will be created only if the queue is full.
Furthermore:
By setting corePoolSize and maximumPoolSize the same, you create a fixed-size thread pool. By setting maximumPoolSize to an essentially unbounded value such as Integer.MAX_VALUE, you allow the pool to accommodate an arbitrary number of concurrent tasks. Most typically, core and maximum pool sizes are set only upon construction, but they may also be changed dynamically using setCorePoolSize(int) and setMaximumPoolSize(int).
Source
Rules of a ThreadPoolExecutor pool size
The rules for the size of a ThreadPoolExecutor's
pool are generally miss-understood, because it doesn't work the way that you think it ought to or in the way that you want it to.
Take this example. Starting thread pool size is 1, core pool size is 5, max pool size is 10 and the queue is 100.
Sun's way: as requests come in threads will be created up to 5, then tasks will be added to the queue until it reaches 100. When the queue is full new threads will be created up to maxPoolSize
. Once all the threads are in use and the queue is full tasks will be rejected. As the queue reduces so does the number of active threads.
User anticipated way: as requests come in threads will be created up to 10, then tasks will be added to the queue until it reaches 100 at which point they are rejected. The number of threads will rename at max until the queue is empty. When the queue is empty the threads will die off until there are corePoolSize
left.
The difference is that the users want to start increasing the pool size earlier and want the queue to be smaller, where as the Sun method want to keep the pool size small and only increase it once the load becomes to much.
Here are Sun's rules for thread creation in simple terms:
corePoolSize
, create a new Thread to run a new task.corePoolSize
, put the task into the queue.maxPoolSize
, create a new thread to run tasks in.maxPoolSize
, reject the task.
The long and the short of it is that new threads are only created when the queue fills up, so if you're using an unbounded queue then the number of threads will not exceed corePoolSize
.For a fuller explanation, get it from the horses mouth: ThreadPoolExecutor
API documentation.
There is a really good forum post which talks you through the way that the ThreadPoolExecutor
works with code examples: http://forums.sun.com/thread.jspa?threadID=5401400&tstart=0
More info: http://forums.sun.com/thread.jspa?threadID=5224557&tstart=450
If you decide to create a ThreadPoolExecutor
manually instead of using the Executors
factory class, you will need to create and configure one using one of its constructors. The most extensive constructor of this class is:
public ThreadPoolExecutor(
int corePoolSize,
int maxPoolSize,
long keepAlive,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler
);
As you can see, you can configure:
Limiting the number of concurrent tasks being executing, sizing your thread pool, represents a huge benefit for your application and its execution environment in terms of predictability and stability: an unbounded thread creation will eventually exhaust the runtime resources and your application might experience as a consequence, serious performance problems that may lead even to application instability.
That's a solution to just one part of the problem: you're capping the number of tasks being executed but aren't capping the number of jobs that can be submitted and enqueued for later execution. The application will experience resource shortage later, but it will eventually experience it if the submission rate consistently outgrows the execution rate.
The solution to this problem is:
Providing a blocking queue to the executor to hold the awaiting tasks. In the case the queue fills up, the submitted task will be "rejected".
The RejectedExecutionHandler
is invoked when a task submission is rejected, and that's why the verb rejected was quoted in the previous item. You can implement your own rejection policy or use one of the built-in policies provided by the framework.
The default rejection policies has the executor throw a RejectedExecutionException
. However, other built-in policies let you:
In picture, consider only addition of tasks are happening
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