Hi Java threadpool very very important topic we are going to cover today and this topic is very important both from the interview perspective and your day-to-day work perspective also so this is one of the interview question which has been shared by one of the engineer that in a thread pool why you have taken core pool sizes two why not 10 or 15 on another number what's the logic so I will tell you the complete question Right uh the candidate has been asked to create a thread pool and this core pool size is the number which
we have to uh Define in the thread pool executor so I'll tell you the complete question also and my solution also right but before telling you the answer we have to first understand what is threadpool and that's where today we are going to cover that from very Basics don't worry about that this questions will come back later right at the end of this video you will I will solve that question so so what is thread pool so understand let's see this three points it is a collection of threads also known as workers or known as
worker thread which are available to perform the submitted task right so what is first point say that it is a collection of thread so this is let's say I have created a collection of threads thread one thread 2 let's say n threads right how many number of thread you can configure whether 5 10 20 1 How many threats you wanted in a pool you can configure but it's a collection of threats which are available to perform the submitted task once the task completed worker thread get backs to the thread pool and wait for the new
task to assign so what happen is whenever any task so these are the task right whenever any new task comes a worker or thread has been assigned to that task so let's say that task one is going to be done By thread one task five it's assigned to thread 2 so this is now busy this is now busy right as soon as uh thread five is busy thread one thread five is busy now as soon as this thread completes its task they will again available in the thread pool right so now thread 1 and thread
five again available and waiting to pick a new task okay so what we are doing is means we are reusing the threads threats can be reused so what generally happen is you Know that till now what we have seen is we have to create thread we have created thread thread one thread 2 thread three whatever the how many number of threads we wanted we have to create our own threads by like we were creating right new thread so we were creating the threads and you know that thread creation takes time why threat creation takes time
because you know that certain memory space need to be allocated to thread Let's say that stack thread stack which is given for each thread so there are certain work right which need to be done when we create a thread so this is little time you can say that it takes some time but with the thread pool you can say that the advantage is that the threads can be reused like we have already created the threats we have already created the threats and we are just reusing it we are not creating new threads every time So
I have already created this let's say five threads I have already created this five threads now any task is coming I don't have to create new thread I just simply assigned that hit thread one you do this task hit thread two you do this task so now you see that I can save some time which time I can save thread creation time right so means we are reusing the threads so this example here if you see that when application submitting new Task right what would happen is so first it will see that is there any
thread which can process this new task is thread available is thread available if yes if yes if thread is available then what would happen is whatever the task is there it will assign to that particular thread let's say task one assigned to thread one task two assigned to thread two Right now let's say task Three is coming now when task Three is coming let's say all the threads are busy we have let's say only two threads thread one and thread two we have only two threads and both the threads are now busy this is also
busy this is also busy performing task one and task two now task Three is coming and there is no thread available what it will do is is we will put into this Q right so we will put the task three Into the Q that so this is uh already been picked up by this thread so task three would be present into the que now as soon as any thread completed its task it will come back to the pool so now thread one is available it's completed its task it will come back to the pool now
it will check hey in this queue any task is pending yes task three is available in the queue so it will pick it up and start performing on that thread one is picking it Up right so you got it in the que also involved in the thread pool which plays an important role so what is the advantage of thread pool you have till now seen that how we used to create thread and his thread has has a life cycle you know right we have created a uh we have understand the thread life cycle we have
created new then we have runable running then wait right and then like exit like end So each thread as a life cycle also right so what are the advantage first of all threat creation time can be saved I told you that whenever we use to create a thread earlier each time there it takes some time to create this thread because there are certain operation need to be done to create a thread like allocation of space what space like stack program counter these are specific For Thread particular Thread right so you have to create memory for
the stack you have to create a memory for the program counter you might have to define something so when each thread is created SPAC is allocated to it and this takes time with thread pool with thread pool pool this can be avoided by reusing the thread so this part this Advantage I think we have already discussed that in the thread pool you have already created the thread now you don't have to with Every request you don't have to create a new thread you just simply use it so little bit performance increase by saving the thread
creation time the second Advantage is that overhead of managing the thread life cycle can be removed if you're not using thread pool on its framework I told you right each thread has its own life cycle currently it's a new state then it goes to runnable running state it might has to go to the weight and then come back To running and when it everything is done you have to finish this thread So currently if you are not using any framework you have to manage the thread you have to manage its life cycle but with the
thread pool and its framework this is abstracted to you you don't have have to do this management executor framework will do for you so thread has different life cycle right running waiting terminate Etc and managing thread State include complexity Like you have to make sure that this thread I have to terminate now I I have to wait it now but with thread pool all this management is abstracted to you right so this is another Advantage it comes and the third is that increase the performance right how it will increase the performance if you see that
let's say you are not using thread pool and executor framewor whenever any task coming task one task two task 100 what your code does is your code Will create a new thread thread one new thread thread two new thread thread 100 so now you don't have control over the thread right every time a task is coming you are creating a new threat so what would happen is you know that I have already explained that if there are more threads means contact switching will happen because let's say there are only two CPU core CPU core one
CPU Core 2 so only these two CPU core have to process This all 100 threads so right so it's not like all 100 threats are running parallely it's seems like a parallel But ultimately internally CPU what it does is contact switching so first thread 1 thread 2 is running then it do contact switch then thread 1 thread 2 is waiting and it is running thread 3 thread four so this is known as contact switching so if more threads are there and you don't have control over the creation of thread then it is Possible that more
contact switching will happen and you know that cont whenever the contact which happen means CPU is Idle that time because contact switching means you are saving the old data bringing the new threads into the CPU and then start processing so during this contact switching CPU is Idle so if you are creating more and more and more threats it is a chance that more context switching time get increased and there would be a wastage of CPU time and CPU Instead of doing processing it just keep on doing contact switching so we threadpool help us to control
the number of threads which we can create which help us to make sure that the contact switching would be very less or we can say that less as much as possible which helps in more processing time and less context switching time okay so there is a framework available in Java in this package Java.util do concurrent package page you will see a framework available so this is an interface top interface executor it has one method execute right so this is the interface this is again an interface which extend from this and it has more methods right
so it manage so this has only execute method like okay you execute your task executor service has more methods like stop shutdown Etc like managing the thread pool more better there can be More functionalities on a thread pool right so this executor service interface expose more methods here if you open executor service it's a child of executor so executor has only one execute right so it will just execute whatever the task runable task which you are assigning then executor service provide some other functionalities apart from execute whatever it is extending from The executor like shutdown
right shut down now is shut down is terminated so there are lot of operations you can say that functionality has been added to this executor service to it and all the threadpool executor these are the child classes these are not these are not interfaces these are classes now this implements this executor surface then we have fog join pool this implements executor surface then there is another interface Scheduled executor service this extended this provide a functionality of like running running a thread on a particular time scheduled we will come to this so we will see each
one of them separately so today I will cover the threadpool executor very very important right thread pool executor it helps to create a customizable thread pool how so now let's first understand The process or you can say that the flow let's first understand the flow so let's say these are the tasks which is coming let's say task one task two task three task four task five these are the tasks which are coming to our executor which executor threadpool executor threadpool executor so what first it will do first it will do is it check any thread
is free in thread pool any Thread is free in thread pool so now let's say that there is a pool here right thread 1 thread 2 thread three only three threads are there five task are coming right so check any thread is free in thread pool so let's say task one is coming and there is a q also okay so task one is coming so this is coming first at T1 it check any thread is free in the thread pool yes all three are free so let's say thread one is assigned to task One so
currently this is not available then task two is coming at time two then it check hey any thread is free in the thread pool yes so thread two is assigned the task two this is also now busy then 3 T is coming at time three any thread is free in the thread pool yes so thread three is assigned task three this is also got busy right so this is the let's say minimum number of thread I have put three so three threads Would always be available right so now when the three task comes this three
thread is assigned to this task now task four is coming now task four is coming at time four it check hey any thread is free in the thread pool no no thread is free in the thread pool what it will do it will put into the Q so task four is put into the this one now let's say task five is coming he any thread is free in this threadpool no then task five is put here Similarly let's say task six task 7 task 8 so this is the size I have given to Q 1
2 3 1 2 3 4 5 so I have given the Q size as five so all now it is filled because no thread is available now uh 4 5 6 7 8 now let's say that task 9 is coming now it says that hey any thread is free in the thread pool no all are busy any space in the que no all Q is also filled up now what should would do Here should we rejected no so now there is one more feature into the thread pool that so first feature I tell you that
minimum number of thread so let's say minimum minimum thread number I have given three so that's why three was there initially there is one more field like maximum thread maximum thread let's say I have given five what does it mean that what is the maximum number of thread can be Present in a pool at a time right so now when this comes into the picture when all the minimum threats which were present into the thread pool first all are busy they are still processing q q size Q size was five 1 2 3 4 5
this is also full now any task is coming it is not finding any free thread it is not finding any space in the Q what this executor framework will do it will see that hey maximum thread is five and Only three thread has been used right so means I can create one more thread so what it will do is at it time it will create another thread thread four and thread four would be assigned this task 9 right so this will not get rejected so thread four has been given task 9 so this this is
also busy now let's say task 10 is coming what it will do first check any thread is free in the thread pool no all four threads are busy can I put into a q no i Q is also full now it will check what is the maximum thread I can have in a pool five and what is the number of pool threads I have in a pool right now four so means I can create one more thread so it created a one more thread in a pool thread five and that thread five will take care
of task 10 right now this is also get busy now now what would happen is let's say task 11 is coming now it will say that okay all Pools all thread in a pool is busy what it will do hey can I put this Tas 11 in a q no Q is also full then it check hey what is the maximum thread size thread pool size you have given five so means maximum I can have five threads in a pool how many I have 1 2 3 4 5 here means I have already created the
five number of threads which is the maximum number allowed in a pool means now I can't do anything I have to reject this Task reject the task here okay now what would happen is let's say thread three has finished this comp thread three has finished its task so thread three is now available so so now thread 3 is available now so now as soon as thread 3 is available what it will do is it will check the que hey any task is spending in the que yes so it will pick one task from here let's
say thread three is now doing task four so this task has been removed from the queue and This is now busy again so this is how it does okay I'll tell I'll explain you more with this parameters but wanted to show you the functionality of the thread executor how the sequence of thread pool and the Q comes into the picture okay so we'll see one more time but first let's understand with this functionality understand the thread pool executor now I hope I'm going slow not running Fast right okay with the basic understanding of this now
let's see the thread pool executor Constructor so here in the thre pool executor and here if you see this is the Constructor right so this is the Constructor if you see that it has lot of parameters right so we will see what is the meaning or purpose of each parameter which we have to be clear very Thoroughly because this only these are the mostly the configuration which help us to create a thread pool so this is a thread pool executor if you create an object of this this will help us to create a thread pool
also so what is the first parameter we have is core pool size core pool size means the number of threads are initially created and keep in the pool even if they are idle so means if you have given this score pool size as three means in a thread pool you Will always find three thread thread 1 thread 2 thread three it create three threads and put it into this thread pool because this is the minimum threads should be available in a thread pool and even if they are idle they are not processing anything they will
keep on waiting here in the thread pool right so this is core pool size then there is another thing called this is not a parameter this is a you can say that a property which has been Set on this object I will tell you but this something called allow core thread timeout I'll tell you that I I I told you that this whatever the core pool size you have tell it will create that many threat into the pool and even if they are idle but if your requirement is that hey if they are idle let's
say for a specific time then remove them then delete those or you can say that terminate those thread right so how we can tell this with this true false Boolean flag allow core thread timeout if this property is set to true then idle thread kept alive till time is specified by keep alive time so there is an parameter called keep alive time so this is only been used when this is set to true if this is set to true then it will check the keep alive time all right and any thread any thread which is
idle for this much of time after this much of time that thread will get removed let's Say keep alive time I have given let's say 5 Second so any thread which is idle for 5 Second till 5 Second it will be alive but if a thread is idle for more than 5 Second this this will get terminated only and only if this is set to true even if you have set this 5 second but this is by default is false and if you uh haven't make it true this parameter is of no use all three
threads will remain active even if they're Idle right even if you have Divine keep alive time is 5 Second even if they're idle for 50 second 1 minute it will not get eliminated why because you haven't made this field to true and by default this is false so whatever the object you will create it so on that object you have to uh set this parameter to true if you want that only this much time a thread which are idle should be alive after That it should get eliminated so keep alive time you know that thread
which are idle get terminated after this time and this will be only used if this is set to true then we have this unit time unit so here this keep alive time you are giving like long it's like you can give five 10 now what does it mean 5 second five 5 hours 5 minutes what ises it so in the time unit we can tell right so here the time unit is for the keep Al Life Time whether It's a millisecond you are selling whether second or hours or Etc what okay so if you're telling
keep alive time is five because it's a long then time unit will say that okay you can tell minute okay 5 minute so after 5 minute if any thread is idle and if this property is set to true that thread will be eliminated okay so time unit is also clear now comes to the maximum pool size so maximum pool size I think with The above this one you already know that when the maximum pool size comes into the picture right just for a quick overview again let's say you have a Q of size 4 right
and you have a thread pool with like minimum three and let's say maximum maximum pool size I am telling five okay so I have already told you the flow that uh first let's say when I have Tell minimum three means thread pool will already keep three threads into here into the thread pool the whatever the minimum number you will get this many threads will already active present already created and present so generally what happen is whenever any task is coming task one what it will do is it will first check any thread is free it
will yes assigned to it so task one thread one like this then task two is coming assigned task Three is coming assigned so all threads are busy now when task 4 is coming it won't just go and create new threat first It Go and first if Q is empty it will put here task four task five is coming all threads are busy it won't create new thread first we we can create two more threads in a thread pool right because maximum we can create five threads in a pool but first it don't create it will
first utilize try to put in a queue thread Five thread uh task five task six task 7 and when task 8 is coming now it say that all three threads are busy all Q is also full now it can't accommodate task it now at that time only it will check okay maximum I can have five threads in a pool I have only three let's create another thread and assign this task to it right if task 9 is coming all threads are busy no space in the queue then only it goes that okay maximum five I
can have in a thread pool I have four let's Create thread five and assign that thread to this one now task 10 is coming all five threats are busy all Q is full it will check what is the maximum threat I can have in a pool five okay already five are there then I can't do anything reject it so this is generally the flow but now one question you can ask to me that hey Shan why we first put into the Q why not we like when the task four is coming why we first put
into the queue when all Three are busy why not we first create a four because it is allowed right maximum we can have five so we can easily create it and assigned to that why we have to put into Q otherwise uh it is just increasing the waiting time right it can be instantly processed this task task four can be instantly processed we can just create a new thread and it start processing it why we have to put in Q and when any thread is finished it will Take read it from the queue and then
process it so this is how it has been done but my reasoning is that why it is done because so now let's say that this this is uh I'm telling you why it might have done you have thread 1 thread 2 thread three minimum is three maximum is five so now let's say thread one is busy thread 2 is busy thread three is busy thread four is coming uh no task four is coming now when task four is coming you You let's say that what we wanted is hey all thread three is busy maximum thread
I can have is five instead of putting into the que let's create another thread thread four right and assign this task to it right and let's say if another task is coming task five we will see that hey it's only four thread maximum I'm allowed five let create another thread and assign this task to it now I'll tell you like why we don't Do this because let's say if thread four and thread five completed its task it will not get eliminated it will come back to this pool and stay keep on waiting for the more
tasks so now your thread pool will be like kind of a full like you have all the threads created right and whatever the minimum pool size I have created I have created in a mind that most average on an average on an average this many threats are sufficient to fulfill most Of the request and if any Peak is coming then I have defined a q that okay if any extra requests are coming let me put into the que and with this three thread they will come and process the request from the que but most of
the time on an average this three thread is sufficient right but now if we are saying that okay every time a new request comes if all are busy instead of putting in a queue if you create a new Thread what we are doing is we created a new thread but once it is completed this thread and thread four will again come back to the thread pool and sit now on an average only your three thread is required minimum three thread is sufficient so thread and thread four is keep on idle is waiting keep on idle
so that's one of my reasoning is that that's why we first try to utilize a q right and with this minimum number itself minimum thread itself we will First try to complete all the request with the help of Q and this minimum thread this is one of the reason why it has been designed that way okay first whatever the minimum threats is used if that is full try to put in Q because that's where our most of the use cases get fulfilled only in certain scenario when the sudden Peak comes all our pool size finished
all our que finished then only go and utilize the max thre because We don't want to reject the request okay so max pool size is clear and I already told you that this is applicable for the whole thread pool whatever the threads are there in the thread pool if this all core thread timeout is set to true then it will check keep alive time if keep alive time you have given 5 minutes then it will wait for 5 minutes and after 5 minutes it will check any thread is free for more than 5 minutes If
yes it will terminate those then worker Q then this work Q uh blocking Q right I have already told you this Q is used to hold task before they got pick up by the worker thread so this is of two uh type of Q bounded q unbounded q bounded Q means Q with fixed capacity like an array blocking Q like here in the above example I have created a q of size four so this is a bounded Q unbounded Q means there is no fixed capacity like Linked blocking que any number of tasks can be
put in a queue like a link list right so that is known as unbounded Q generally this one is preferred bounded Q right unbounded Q it's generally should be avoided and bounded CU is mostly preferred because we want full control how much request can be put in a queue right and here task is Kept and your worker thread will pick from this task as soon as they they get free so the task get picked up by the worker thread from here okay so this is also clear then we have thread Factory what does thread Factory
means so thread Factory means it give you a you can say that it provide you an interface right where you can give custom thread name thread priority uh thread priority and the demon Flag so let's say you want to give a thread name because you know that this framework itself will create the thread pool executor itself will create a thread so it will give the thread name of its own it give the thread the priority of its own and if you want to uh thread demon or Not by default it is false it will give
it on its own but if you want to override that property you can provide your own thread Factory right and you can create tell like what Is the thread name I want to give what is the thread priority I want to give whether This Thread is a demon flag demon or not you can set those right we will see an example rejected execution Handler this last parameter what is this like I told you that Q is full all Q is full thread pool has full thread 1 thread 2 thread three thread four thread five minimum
is three maximum is five so all Five maximum has been created and it is full all are busy now any thread is coming new task is coming now it will see that hey any task any thread can can is free no any Q SPAC is there no can I create a new task can I create a new thread no already five threats are created it is maximum then this has to be rejected now what to do how to handle this rejected task so that's where the handler comes into the Picture so it is a Handler
for the task that cannot be accepted by the threat pool generally what we do is we do logging here in this case that this task is rejected so we can put a log here for debugging purpose but if you have another functionality you can do that but they are different these are the four types of Handler already exist in the Java which you can use or we can create our own I will show you how to create our own so let's say this is the One policy rejected execution Handler this is the abort policy what
it will do is it will simply throw exception whenever any task is rejected it will throw an exception that hey rejected execution exception this comes then there is something called discard policy let's see this discard policy that silently discard the rejected without throwing any exception if you're using this Handler Here in this uh request and any task is rejected it is you won't know right it just simply discarded it callers run policy what it will do is that EX execute the rejected task in the caller's thread thread that attempted to submit the task so I
told you right task is submitted application submit the task somebody submit the task right that also might be running in one thread let's say by default is main thread so some thread Is running which submit the task to this thread pool executor right so if threadpool executor cannot take this handle this new task and if you have defined this rejected execution as a Handler then on this thread it will try to run this task executed the rejected task in the caller thread thread that attempted to submit the task then we have discard oldest policy What
does it mean discard the oldest task in the queue to accommodate the new task so if you have used this what it will do see that it will see that hey what is the oldest task in this que it will discard that and put this new task in it so there are different types of you can say that implementation how you want to handle the rejected task okay so this is the threadpool executor mostly you can say that the Configuration which is required right and you got it right what is the flow when it comes
so this is the life cycle of a threadpool executor I after that we will see an example right that would become more clear so first phase of a life thread pool executor is running so in the running executor is in running State means submit method will be used to add New task means it can accept new task when the threadpool executor is in running State means you can add new task task one task two task three it can accept right then there is another called shutdown let's say that if on this running if you have
called the shutdown so there is a method called shutdown what it will do is shut down is now executor do not accept any new task but continue to process the existing task so now let's say that task One task two is already running by thread one thread 2 but when shutdown is called now in thre uh thread executor it will not accept any new task let's say task three it want to submit now it will not accept because now the thread executor is in shutdown mode it will not accept any new thread but it will
let this two task to continue to process it and once this two task complete done it slowly move to the terminated state where all the threats Will get eliminated then there is a uh status called stop this is again a life cycle which is you can say that the force shut down and there is a method called shut down now so what it will do is it will stop the executor to accept any new task plus it also makes forcefully stop the existing threads which are running and move to the terminated state where All threats
will get eliminated so you got the difference between shutdown and stop shutdown will only stop accepting the new task but allow this already task which are running let them complete and then move to terminated after they successfully completed stop will forcefully stop accepting the new task plus also stop the existing which are running and then move to the terminated and once it is terminated Done uh the life cycle of the thread pool is done all the threats are eliminated everything is done right there is no way back and there is a method called is terminated
which you can use to check whether the thread pool executor terminated or not okay so till now we have seen the threadpool executor and its configuration values now let's Implement one example out of It okay I will let's first implement it then I will show you here right and our agenda would be to validate our understanding uh our understanding would be that so this is what we will create so this is the thread pool which we wanted with minimum uh let's say We'll create uh two all right uh maximum I will create let's say uh
three or let's say maximum I will create four Q size I will create let's say for example one only or let's say two 0 1 right and how many tasks task one task one task two task three task four four tasks are coming let's say so use case one so what should be the expected Behavior so we will see that one so let's first code for this one then we will uh do the dry run and see the expected behavior and run it so let's run this uh let's first create the Code this is the
main method let me Zoom it a bit more okay shall I zoom it more this is okay right let me Zoom it more in case okay so what we wanted we first want to create a threadpool executor object threadpool executor uh this is my executor H let's create a thread pool Executor Constructor now in the Constructor these are all things which we have to design minimum core pool size we wanted two maximum pool size four keep alive uh let's say yes I want to keep alive uh for let's say 10 but it should be I
want to keep it for minutes let's say that time unit is I want to give minutes then I have to define a blocking Q of size two so I Am create creating new array blocking que of let size two thread Factory and rejected execution Handler so yes I want to uh Define so let's uh have this first Define our own thread Factory let first so class my custom thread Factory implements thread Factory so this is an interface so I Have to implement its method okay so either is like I need to Define my own custom
Factory or I can use which is available in this one default thread Factory but for this demo I am showing a custom thread Factory so I have to create one thread new thread and right whatever the runnable task This Thread has to run that uh thread but I want to set another properties like thread dot set priority I want to set its uh thread Priority as normal priority and also I want to make it is demon uh set demon Falls it is not a demon I just want to show you this is the by default
actually even because even in the default uh thread Factory this is it is used but I want to showcase that in the custom you can change this value and return the thread so I have created a thread which will perform whatever the runable task Whatever the task it would be assigned but I have you can Define the thread dot set name you can set the name also for the thread which you wanted so I want this custom thread right and similarly the last object is rejected execution Handler so here if you see that there are
already existing uh threadpool abort policy discard holders Discard policy right I can use this one this is just like Handler reject the task silently it just reject it silently doesn't do anything if I use discard oldest policy what it will do it will check from the Q it will pull it first because at the front this is the oldest St so it will pull it first and then it will execute this well it will add it Right and if you go into the execute part you will see the three step first step is if thread
is available assign the task to it second is if all threads are busy inside a pool see if a task can be successfully queed if a task cannot be successfully queued then the third step if you cannot queue task then we try to add a new thread because maximum let's say if there is still a maximum we can create if that is also not possible then only Reject that's what we have seen till now okay so this is the discard add policy but let's say we want to create our own so I am creating my
own let's say class custom reject Handler implements this so this is an interface I have to implement the method let's say I want to log it so here I'm doing system. out. print Ln task rejected right so I can have this I have uh this is the task only right and this is the executor which try to perform this task which doesn't have so I can use this information r dot to string what is the name and all you can print that one right for your debugging purpose you can take out the information from this
one and use this part thread executor what is the executor name group name thread Name so you can add that right so these are all the methods which are available so you can put this two string here so I want to use my new custom reject hand law so this is the executor which I created okay now I am doing I = to 0 I less than uh let's say I want to create four tasks right I want to create four tasks so That's what we are trying to do here so thread pool minimum configuration
I have tell maximum configuration I have tell the Q I have tell and I have tell the this are the custom Factory for the name and this one but this I have tell now I have to submit this right executor dot submit this submit takes the runable like and you know how to create a runable task I can use this Lambda Expression right so so now I am creating this uh let's say that this is the task which has to be performed by a thread um let's say system.out.print Ln task let's say this is the
task this is the task which is getting processed task processed by what is the thread which is going to which is processing it I'm just printing that let's say this is a thread And just to simulate that this task takes certain time I am sleeping this thread for let's say 5 Second and this I need to put in TR crash block okay so now what I am doing is I am submitting this task what is the task this you know how already how to create a there are two ways to create a task right through
Implement and through extend so I am creating a runnable task here so because it accept a runnable task so you can create a runnable task Using by creating a separate class or through Lambda expression itself because this is your functional interface that's why you should be already uh familiar with this now we have already covered this so I have just make a 5c sleep to make sure that yes something is working right uh and then printing out that yes task process by this thread okay now how many threads I have created four how many uh
how many task I Have created four so four task I submitting so task one here so task one it is submitting so now what would happen is you have a thread executor task one task two task three task 4 so four task I have called submit submit submit submit right and this thread pool executor have two threads minimum so we Have told two as a minimum right so it will have thread one here thread to here right and what is the Q size two 0 1 this is the Q and what is the maximum it
can create four now we want to verify that what should be the when if I run it and in the finally and after once everything is completed we have to make it shut down shut down means thread should also get eliminated after this One now what should be the behavior let's say task one is coming so thread one thread one or let's say this thread zero thread one like how it generally give thread Z thread one two threads right so thread zero is assigned Tas one busy now the this task is coming thread one is
assigned task two this is also busy now now task Three is coming now what it will do is no it will not create new Thread yeah I can have four threads in this thread pool but it will first try to put in Q so it will put here thread three because both the threads are busy because I have kept 5c uh sleep right so they are still processing then thread four is coming both the threads are still busy it will be put here and after they finished working so they will again goes back to the
pool now they are available now the same Threads thread zero only will do let's say task three thread one only will do task four so only these two threads will take care of all these four requests no new thread will be created let's first see that one I'm running it up task processed by thread one thread zero so two threads has been created thread zero thread one so two TS has been created so this remaining two threats Has been put into a pool right q and once this two threads got free they only pick the
remaining two Tas from the que see thread zero thread one only so only maximum two threads created which was initially with set right so this code is working as expected but what would happen if I had task five here now when the task five is added what would happen here now what should be the Behavior Now so task one is busy by thread zero task two is busy by thread one task three is put into the que task four is put in the queue task five comes when task five comes can any of the thread
pool can be used no thread zero is busy thread one is busy can I put in a q no then it goes and see that hey can I create new thread yes four thread can be there thread pool has only two you can create new thread so new thread would pick task your Five right and then this uh any of the thread which get completed it will goes back to the pool and do this thing like maybe thread zero will put task three from the queue and thread one goes back and pick four but here
if you see that this new thread should have been created so now let's simulate this and create five task run it so thread zero thread 1 thread 2 and so Thread zero thread 1 thread two and two task are waiting so any of this two threats will come back and pick this stop this is working expected right so our understanding is correct right so first it try to use whatever the threats are there in the pool if it is all are busy it will first put into the que if that is also full then only
it will go and try to create a threat if we we are allowed maximum is not reach but what if in maximum is also Reach so uh maximum four and six so let let's say if I create seven so at Max all four thread it will create 5 six so six thread it will do and whenever the seventh request will come one will fail one would be rejected and once it is rejected it will print this let's do this task rejected one is rejected and rest is processing how let's see that its functionality Now okay
so let's simulated it so here initial word two thread 1 thread two thread zero thread zero thread one and task six task seven I am submitting okay so first task one comes thread zero pick task one this is busy task two coming thread one pick task two this is busy task Three is coming it put into here task four is coming it is put over Here task five is coming this is busy Q is full it will create one thread so create one thread thread two now doing task five this is now busy thread six
is coming all threads are busy Q is full it create one more thread thread three and it is assigned this task six this is now busy thread seven is coming all four thread is busy Q Q is full can I create more thread No 1 2 3 all four threads maximum has been reached this has been Tas 7 has been Rejected right and after that any of the thread which come back to the pool they will pick let's say thread zero go and uh pick the task three or thread one go and pick the task
four right so generally what this is one task is rejected the task which is rejected is this one right and there should be 0 1 2 3 four threads different four threads thread one thread zero thread 1 thread 2 thread three four different threads created and Uh two task were there in the queue so any two threads which come first into the pool again they will pick it from there so thread zero thread one pick the two Tas from the cube got it so this example example is here right so you understand what is the
purpose of pool when the maximum pool size keep alive right so here I can to use this keep alive you know that it it will only be used When executor do allow code timeout to true then only this keep alive would be used for after 10 minutes if any thread which is Idle into a thread pool it will now get eliminated with this okay so thread pool creation is clear if this is clear now let's come to the interview question why you have taken core pool sizes two why not 10 why not 15 or any
other logic okay so you now understand that Interviewer might have asked the engineer to designer or implement the threadpool executor so engineer might have done the same thing it might have created a threadpool executor for the question and they have picked any random number let's say I'm creating a minimum two maximum four but now that's where the followup question come why four why 2 why four why not I create a 20 why not I create here 10 why you have taken two what is The reasoning behind taken certain numbers so the question is what is
the reasoning behind to decide what core pool size should be minimum and maximum so again this is my theory and my answer this is very subjective question lot of different Engineers might have different answer but I will tell you generally the thread pool minimum and maximum size are depend upon various Factors like CPU core very important factor you know right why CPU core is important I told you in a start that if you have only two CPU core core One Core two and if you create 100 thread thread 1 thread two thread 100 you know
that most of the time they will spend just do contact switching right because only maximum two threads can be run in parallel right after that CPU has to do contact switching and pick another two Threads into here thread three thread four but it has to save the thread one thre two till where it has run it has to save it so there is a lot of contact switching happen so we this is become very important CPU core we have to consider this second is jvm memory you know that everything our program which runs in a
jvm memory jvm has different memory like Heap and the thread each thread get certain memory like stack space and they also get certain like a program counter like and other spaces so there is a space allocated for each purpose so we can't just create as much as thread as possible because jvm let's say if you have given 2 GB then you have a limited resource now you even let's say your core are so many cores you can do very fast processing your Codes are super fast but your memory is only 2GB then definitely you can't
create 100 threads here there is no space at all to keep it so this also comes into the picture important then you have to consider the task nature whether it's a CPU intensive or IU intensive so you know that there are two type of task CPU and IO intensive CPU intensive means they want more CPU time more processing time And IO means that uh let's say you want to write something into uh you want to read something from the DB there is a DB call or there is an external call so thread is Idle during
the io call so when thread is idle it is better to have more threads so that CPU should not wait CPU can just do contact switch Let it wait which thread is waiting for input output operation by the time CPU can process some other Thread so if it is CPU intensive less thread should be there if it is IU intensive more thread we should be keeping why because all the if it is IU intensive operations mean means your thread will go on idle whenever IO is requested IU operation is requested so CPU can pick another
thread so this is generally also has to be considered what is the nature of the task whether it is a CPU intensive if it is a CPU intensive the number of threat should be less if It is an IO intensive number of threats can be more concurrency requirement that yes I want a high concurrency low concurrency medium concurrency memory required to process a request now let's say that one post request is coming if it that requireed 10 MB to process it because when post request is coming it loads so many data from DB so many
data from service call let's say and it store Into inmemory where Heap and Heap is also has a limited space right so if one request takes 10 MB now let's say that I can have 10 100 threads if 100 threads accepted this post request and each request takes 10 MB do you have sufficient memory here in the he so that also we have to consider that the memory required to process a request that much he can support or not right so and throughput like how fast you can process the Request so here if you see
that we have to and there could be ET there could be more but these are the major you can say that factors on top of my mind which has to be configured before we comes to this minimum and maximum size okay now let's say that okay sh let's consider some estimate for it and let's come to this one okay before I consider the estimate like okay these are 8 core 32 core 64 core and come up with a number I will want to tell you Certain formulas so there is a formula available here to find
out a maximum number of threads but again this formula is not full proof this doesn't even considered all the factor this is just give you what is a maximum you can have right or what is at least if it will give you a start point you can say that so what does it say that the number of CPU core into 1 plus request waiting time divide by processing time actually this formula is nothing but focusing on this two task nature and the CPU core right and uh it also consider throughput so let's say that my
CPU core is 64 core 64 into 1 plus now what isse actually we are doing here I told you right CPU intensive and IO intensive so request waiting time So let's say if it is a CPU intensive request waiting time would be very less and processing time is more if it is IU intensive request waiting time would be more processing time would be less so you should be clear like what type of operation do I doing so let's say I am assuming that my CPU core on my server is let's say 64 request waiting time
is 50 milliseconds divide by processing time is 100 so you can say that it is more CPU intensive than IO so iio is less CPU processing time is more so you can uh estimate you can discuss with the interviewer that what should be the it is high CPU intensive if it is high CPU intensive mean you can say that this request waiting time divide by Pro uh process time would come near to zero right so here if you see that this ultimately give you around 64 only so means since it I took as a CPU
Intensive that 100 millisecond it is spent to process a Time 50 millisecond half it is spend in IO processing so it come something 64 something so I have taken an explo 64 so number of CPU core which can be required uh is that 64 can we can have a maximum number of this threats right so let's say you have 64 CPU core Core 1 Core 2 core 3 core 64 if it is a high CPU intensive task means it is better to have this many Threats itself so that they can run parallel there would be
very less contact switching or no contact switching at all all right because it's a high CPU intensive everybody wants CPU time so it's better to have the number of threads equals to what the core you have and this formula is also give you the uh the same thing if the whatever the core you have into 1 plus if you it is high CPU intensive this is will give you Around near to zero let's say waiting time is only 2 millisecond and processing time is 30 milliseconds out of 32 only two is waiting time 30 is
processing time so it is come very equivalent to zero so how many threads you can have is number of CPU core but is this the correct solution right okay we have come up with the number of threads but does it considering the memory no this formula do do not even consider the memory now We have to go to the step two this formula doesn't consider the memory yet now let's estimate the jvm now let's say that I have given jvm 2 GB space now in jvm there are multiple things required Heap I give 1 GB
there's a Code cach space where the code has been kept 128 MB let's say jvm required some other uh task and they required I have kept 256 MB for jvm overhead we don't know what all task jvm does right not in our Control but it required a space for that let's give 256 MB out of it so how much space left let's see that so 1 GB 1,000 let's say that 1,000 MB plus 128 MB plus 256 MB right plus X = to 2 gb jvm space let's say 2,000 MB right so how much it
will come your so it would be let's say 300 400 I think around, 1500 let's say this is consumed so 500 MB left so there might be a calculation mistake I'm Just taking estimate just guessing so this let's say 500 MB left so out of this 500 MB you know that we can now can be accommodate For Thread now for each thread you need to create a stack you need to create a register and there are other things which thread is stored so for one thread you need let's say 5 MB let's say 2 MB
you have given for stack right 1 MB for this so let's say one thread takes 5 MB And we have 500 MB left so how many threads we can create maximum here in this space which is left is 100 let's say 100 threads we can create okay so now we got another part like okay with this formula we know know that 64 thread is good to go but this doesn't even consider the memory but here we have considered the jvm memory jvm tells that okay maximum 100 threads we can create this much space jvm can
create because one thread create 5 MB we Have 500 MB left in the jvm so 100 threats let's say we can create but can is this again a good number like this many threads actually can work together now we have to consider this memory required for process to request now let's say that one request require 10 MB because it has to load data from DB it has to load from it has to make external call load data from there let's say that it want to store certain 10 MB Of data in at a time and
that where that would be stored into the Heap now if you're are saying that if 100 threads are created if 100 threads are created and each thread process one request and one request take 10 MB how many space is required 1,000 MB let's say 1 GB so means it required full Heap space your HEAP would be full that is risky again so we can say that we can put certain buffer and we can use let's Say 60% or 70% of Heap because it might be might need a heap for some other task also so let's
say we can create 60 thread so 60 into 10 MB 600 MB at a time this memory can be used of a heap it's okay we have 1,000 MB in heap if you create 60 threads 600 MB would be use okay so this number I can say that yes it is safe to use 60 % of the Heap memory for the threads so what is the maximum thread I can create is 60 right based on the memory constraint And this formula say that okay you can maximum use 64 so that's where I can say that
okay minimum I can give 60 maximum I can give 64 or around to it let's say 70 and then there I can do monitoring and there different tools to monitor like profiling tools are there now but what I'm meant to say now you have to do iterative monitoring right you have to perform load testing with this number and say That yes this number is fine or not and optimize this number but this is just one way to at least answer that yes we have to consider all this like we have considered CPU core and the
task nature and then we have come up with with one number but this number doesn't even consider memory right so if you consider the memory Heap memory and the jvm memory like uh what is the space is available for the threads then based on that you will again get what is the Maximum what is the maximum you can create and based on those number you can Define your minimum and maximum and then you can tell that I can do iterative and load testing andine this numbers okay so I think today's session is very big and
this is very important topic it's interesting also but these are the next I will cover again an important part but do check out this Video again if it is not clear or ping me we can discuss more and do practice it also man like code it out right and practice this thread pool very very important okay guys thank you bye