Thread life cycle in java

In a recent post, we have seen what is the thread in java and thread creation in java. Let’s understand the Thread Life Cycle in Java and Thread State in java. If you want to learn multithreading in java, you must know about the life cycle of thread in os. We will explain thread life cycle in java with a different example.
Each thread is controlled by the Thread scheduler. A thread can be in any states which are the following:

1. NEW state
2. RUNNABLE state
3. RUNNING state(This state doesn’t exist)
4. TIMED WAITING state
5. WAITING state
6. BLOCKED state
7. TERMINATED state

Thread life cycle in java

thread life cycle in java

1. NEW state

It is the first state of the thread after the creation of a thread. When we create a thread object by use of the new operator, the thread enters in NEW state. In this state, the thread is not considered alive. A thread keeps the NEW state until JVM calls the start() method. Once JVM calls the start() method, the thread leaves the NEW state and move to another state. A thread can’t move back to the NEW state after the call the start() method.

NEW state of thread

2. RUNNABLE state

When the JVM invokes the start() method on thread object, the thread leaves the NEW state and move to the RUNNABLE state. Meanwhile, the control transfers to the Thread scheduler to finish its execution. The thread scheduler decides whether to run the thread instantly or keep it in a runnable thread pool before running. If the thread is in the RUNNABLE state it means the CPU can run it at any time. When the thread gets a chance to run its states will be changed accordingly. It is the responsibility of the thread scheduler to give the chance to thread.
The thread in a RUNNABLE state is considered to be alive and it can be returned back to this state from the  WAITING, BLOCKED state.

NOTE : In RUNNABLE state a thread can be either running or ready to run.

In multi-threaded program can have multiple threads.  The thread scheduler allocates a fixed amount of time to each individual thread. Each thread gets CPU for a short-fixed time and then pauses so that other threads can get a chance to run. When the execution of a thread is pause by a thread scheduler, the thread is ready to run, and it is waiting for the CPU. It means the thread lies in a runnable state.

RUNNABle state of thread

3. RUNNING state

The RUNNING state doesn’t exist in reality, but it’s considered as a part of the RUNNABLE state. As we know in a RUNNABLE state, the control transfers to the thread scheduler and the thread scheduler pick one of the thread from the runnable thread pool and change its state to Running. It is the state when the CPU executes the code of thread. 

4. TIMED WAITING

A RUNNABLE thread can move to the TIMED WAITING state for a specific time interval. Meantime the CPU picks another thread that is ready to run and waiting for the CPU cycle. When a thread is in the TIMED WAITING state it means that thread lies in this state for a specified time period. It will remain in this state until the given time interval expires, or a notification is received. Any thread can put in a TIMED WAITING state when it calls a method with a time out parameter.
There are some methods that are used to moves the thread in TIMED WAITING state like sleep(time), wait(timeout), join(timeout), parkNanos(), parkUntil().

Let’s understand it with an example. If there are two threads T1 and T2. T1 thread will take one hour to complete their corresponding job and T2 thread will take 10 seconds. Let’s say T1 thread is in running state and T2 thread is in the RUNNABLE state(Ready to run and waiting for the CPU cycle). In this scenario, the T2 thread has to wait for 1 hour to complete the execution of 10 seconds. To execute the T2 thread in between we can call the waiting(timeOut) method and move the T1 thread in the TIMED WAITING state because T2 needs to execute only for 10 seconds on priority. Now T2 will move to the running state and get the CPU. The thread T1 is in the TIMED WAITING state only for the 10 seconds. The T1 thread will be again in the RUNNABLE state only if the given time will be expired or any thread gives the notification. It is the responsibility of the thread scheduler to determine which thread should be run.

thread life cycle in java

5. WAITING state

When a thread is in the WAITING state, it means some other threads are on priority. A thread can be in the state for various reasons. We can put a thread in the WAITING state by calling its wait() method, join() method or park() method.

For example: If there are two threads T1 and T2. T1 will take one hour to complete their corresponding job and T2 will takes 10 seconds. Let’s say T1 is in running state and T2 is in the RUNNABLE state(Ready to run and waiting for the CPU cycle). So, we call the waiting() method and move the T1 thread in WAITING state, because T2 needs to execute only for 10 seconds on priority. Now T2 moved to the RUNNABLE state and get the CPU. The thread T1 in the WAITING state is scheduled by the thread scheduler. Once the thread wait state is over its state is changed to runnable state and it’s moved back to thread pool. It is the responsibility of the thread scheduler to determine which thread to run.

6. BLOCKED state

When a thread is in the BLOCKED state it is not eligible to run. Although the thread is considered to be alive. A RUNNABLE thread can move to the BLOCKED state if a thread wants to perform some operation but can’t complete immediately so it must temporarily wait until that task completes. After the BLOCKED state, the thread moves to the RUNNABLE state and waiting for the CPU cycle.

For example, A thread is waiting for I/O operations, but the I/O operations are already occupied by some other thread. So now thread must wait for I/O operation, and it lies in the blocked state. It’s the responsibility of the thread scheduler to reactivate and schedule a blocked thread. A blocked thread can’t be executed further until it is moved to a RUNNABLE state. The threads which are in blocked states does not consume any CPU cycle.

If there are two threads T1 and T2. T1 is in the RUNNABLE state(Ready to run and waiting for the CPU cycle) and T2 is running by CPU. If T2 (running thread) is moved to the blocked state, then another thread(T1) in the runnable state is scheduled by the thread scheduler to run. It is the responsibility of the thread scheduler to determine which thread to run.

thread life cycle in java

7. Terminated state

It is a dead state of the thread. This state, the thread does not consume any cycles of CPU. A thread terminates because of some reasons:

  • The first one is when a thread is finished its execution completely. It means it completes the execution of run() method.
  • Second is when there occurred some unusual erroneous event, like segmentation fault or an unhandled exception.
class MainClass extends Thread
{
  public static Thread thread1; 
  public static Thread thread2; 
	
  public static void main(String arg[])
  {
    thread1 = new MainClass();
	
    // thread1 is just created so now it is in NEW state
    System.out.println("Getting the state of thread1 after creation of thread1 = " + 
    thread1.getState());
				
    thread1.start();
				
    // Start() method moved the thread1 to RUNNABLE state
    System.out.println("Getting the state of thread1 after call start method by thread1 = " 
    + thread1.getState());
   }
   public void run()
   {
     thread2 = new ExampleOfThreadStates();
	 
     // thread2 is just created so now it is in NEW state
     System.out.println("Getting the state of thread2 after creation of thread2 = "+  
     thread2.getState());
					
      thread2.start();
				
      // Start() method moved the thread2 to RUNNABLE state
      System.out.println("Getting the state of thread2 after call start method by thread2 = 
      " + thread2.getState());
		
      try  
      {
	// The sleep method move the thread2 in TIMED_WAITING and thread1 in RUNNABLE. 
        // Because sleep method is used to sleep the current executing thread.
	Thread.sleep(500);
	System.out.println("Getting the state of thread1 after call the sleep method = " + 
        thread1.getState());
	System.out.println("Getting the state of thread2 after call the sleep method = " + 
        thread2.getState());
       } 
       catch (InterruptedException e) 
       {
	  e.printStackTrace();
	}
		
	try 
	{
	  // Now join method is called by use of thread2 it means thread1 can't be execute 
          // until thread2 execute completely.
	  thread2.join();
	} 
	catch (InterruptedException e) 
        {
	   e.printStackTrace();
	}
		
	System.out.println("Getting the state of thread1 after completion of thread2 = "+ 
        thread1.getState());
        System.out.println("Getting the state of thread2 after completion of thread2 = "+ 
        thread2.getState());
      }
}
class ExampleOfThreadStates extends Thread
{  
	public void run()
	{	
		try
		{ 
			Thread.sleep(1500); 
		} 
		catch (InterruptedException e) 
		{ 
			e.printStackTrace(); 
		} 
               System.out.println("Getting the state of thread1 after calling the join by 
               thread2 = "+  MainClass.thread1.getState()); 
               System.out.println("Getting the state of thread2 after calling the join by 
               thread2 = "+  MainClass.thread2.getState()); 
	 }
} 

Output:
Getting the state of thread1 after creation of thread1 = NEW
Getting the state of thread1 after call start method by thread1 = RUNNABLE
Getting the state of thread2 after creation of thread2 = NEW
Getting the state of thread2 after call start method by thread2 = RUNNABLE
Getting the state of thread1 after call the sleep method = RUNNABLE
Getting the state of thread2 after call the sleep method = TIMED_WAITING
Getting the state of thread1 after calling the join by thread2 = WAITING
Getting the state of thread2 after calling the join by thread2 = RUNNABLE
Getting the state of thread1 after completion of thread2 = RUNNABLE
Getting the state of thread2 after completion of thread2 = TERMINATED

In this example we have two classes, one is MainClass and another is ExampleOfThreadStates.

In MainClass we have created two threads:

  1. Firstly, We are creating a thread in the main method which is thread1. We call thread1.start() and it runs the run() method of MainClass. In run() method are creating another thread thread2 of      ExampleOfThreadStates.
  2. Now thread1 and thread2 both are in executing by CPU. Both are sharing the time slot allocated by the CPU.
  3. In the next line, we are calling Thread.sleep() and thread2 moves to TIMED_WAITING state. Because sleep() method is used to sleep the currently executed thread.
  4. The thread2 will remain in TIMED_WAITING state until the timeout is completed. So thread1 continue with the execution.
  5. In next line thread2.join() is called. It means thread1 can’t be executed until the thread2 executed completely. The thread1 moves to WAITING state and now control flow goes to thread2.
  6. The thread2 completes the execution successfully and moved to the TERMINATED state and the control flow goes to thread1.
  7. The thread1 moves to the RUNNABLE state.
  8. After completing the run() method of MainClass the thread1 moves to TERMINATED state.

Leave a Comment