Initially when we create a Thread in java program, its state is New. When we start the thread that changes its state from New to Runnable. Thread Scheduler is responsible to allocate CPU to threads in runnable thread pool and change their state to Running. Other Thread states are Waiting, Blocked and Dead.
When we create a new Thread object using new operator, thread state is New Thread. At this point, thread is not alive and it’s a state internal to Java programming.
When we call start() method on Thread object, its state changes from New to Runnable. The control is given to Thread scheduler to finish its execution. Whether to run this thread instantly or keep it in runnable thread pool before running, depends on the OS implementation of thread scheduler.
When thread is executing, its state is changed to Running. Thread scheduler picks one of the threads from the runnable thread pool and changes its state to Running. Then CPU starts executing this thread. A thread can change state to Runnable, Dead or Blocked from running state depends on time slicing, thread completion of run() method or waiting for some resources.
A thread can be waiting for other thread to finish using thread join or it can be waiting for some resources to available. For example, producer consumer problem or waiter notifier implementation or IO resources, then its state is changed to Waiting. Once the thread wait state is over, its state is changed to Runnable and it moves back to runnable thread pool.
Once the thread finishes execution, its state changes to Dead and it is considered to be not alive.