The lifecycle of the Thread can be described as follows.
According to the above diagram, a Thread object can be in one of the following life cycle statuses.
When the thread object is created it is in the new state.
Thread threadA = new Thread();
Now the threadA is in the new state.
This is commonly known as “ready to run state“. Here the thread object is started and ready to run. There will be multiple thread objects in this state and it it the responsibility of the Thread scheduler to select a thread object for running. The thread object in new state can be moved to Runnable state by calling the start() method on it.
Thread object can be started only once. if you try to start it more than once, it will throw IllegalThreadStateException.
If the Thread scheduler has selected a thread from runnable state and call the run() method, then it is in the Running state. Here the run() method is still executing and not competed yet. It is important to note that the run() method must be called by the Thread scheduler.
This is also known as blocking, sleeping or waiting state. The currently running thread can be moved to “Not Runnable State” due to several reasons. for instance
- calling the sleep() method
- calling the wait() method on the shared resource
- calling the join() method etc….
In this case, the execution of the running thread might be hold and moved to not runnable state from running state.
Back to Runnable from Not Runnable state
The threads that are in the not runnable state can be moved to runnable state again on following situations.
- sleeping/waiting time has expired
- call the interrupt() method
- call the notify()/notifyAll() on waited resource/object
After it is moved back to the runnable state, it is the responsibility of the thread scheduler to select them and resume their execution.
Once the run() method is completed, the execution of the thread object will be over and thread will be moved to the dead state.