In C#, the lifecycle of a thread is divided into five different states in which a thread may enter during its lifetime.
Each thread can be in one of the following five states. Let's understand
each of these different states in the order in which they are mentioned below -:
A thread enters the unstarted state when an object of Thread class is created but the Start() method hasn't been called on it yet.
In the unstarted state, a thread is not considered alive as it's not a thread of execution.
Once the Start() method is called on the thread,
it leaves the unstarted state and enters the next state but once it leaves
unstarted state, it's impossible for a thread to return to this in its lifetime.
Note: The unstarted state could also be termed as the new state.
A thread enters the runnable state when the Start() method has been called on it. It means, that a thread is eligible to
run, but it's not running yet, because the thread scheduler hasn't selected it to run.
At one point of time there could be multiple threads in the runnable state within the thread pool,
and it's always the choice of thread scheduler to decide which thread from the runnable state should be moved to the next state.
A thread in runnable state is
considered to be alive. A thread can return to a runnable state after coming back from a sleeping, waiting/blocked
or running state.
A thread enters the running state, when the thread scheduler has selected it to run(out of all the threads in the
thread pool). In this state, a thread starts executing the Run() method and it is alive and kicking.
From the running state, a thread can enter into not runnable/waiting/blocked state, runnable state, or the final,
Let's depict these states too through a diagram -
Not Runnable State
A thread enters the not runnable state in one of these situations -:
When a thread has called the Wait() method on itself and it is waiting for the other thread to notify it or wake it up.
When the Sleep() method is called on a thread, asking it to sleep for a duration.
When a thread has called the Join() method on another thread,
which makes the first thread wait until the another thread has finished its execution.
When a thread is waiting for an Input/Output resource to be free.
Apparently, some may also refer to this state as the WaitSleepJoin state.
When a thread finds itself in any of the above mentioned situations, such event pushes the thread into the
not runnable state and the thread is no longer eligible to
run, but even in this state, the thread is still considered to be alive.
Note: When thread gets out of this not runnable state, it re-enters into runnable state.
This is the last state in a thread's lifetime. A thread enters the dead state after it has successfully
completed executing its entry point method i.e. Run(), or when the Abort() method has been called on it to abort its execution.
In this state, a thread is considered to be not alive
and hence if you try to call Start()
method on a dead thread, it raises the ThreadStateException exception(which we will read about in an upcoming article).