Life Cycle of Thread in Java | Thread States

Life Cycle of Thread in Java is basically state transitions of a thread that starts from its birth and ends on its death. When an instance of a thread is created and executed by calling start() method of Thread class, the thread goes into runnable state.

When sleep() or wait() method is called by Thread class, the thread enters into non-runnable state. From non-runnable state, thread comes back to runnable state and continues execution of statements.

When the thread comes out of run() method, it dies. These state transitions of a thread are called Thread life cycle in Java.

To work with threads in a Java program, it is important to identify thread state. So, let’s understand how to identify thread states in the thread life cycle.

Thread States in Java


A thread is a path of execution in a program that enters any one of the following five states during its life cycle. The five states are as follows:

  1. New
  2. Runnable
  3. Running
  4. Blocked (Non-runnable state)
  5. Dead (terminated)

State transition diagram for life cycle of thread in Java

1. New State:

When we create a thread object using the Thread class, the thread is born and enters the New state. This means the thread is created, but the start() method has not yet been called on the instance.
Thread in new born state

In this state, the Thread object exists but it cannot execute any statement because the execution of thread has not started. Only after calling the start() method does the thread move to the Runnable state. In other words, the thread remains in this state until you start its execution by calling the start() method.

Only start() method can be called on a new thread. If any method other than start() is called while the thread is still in the NEW state, an IllegalThreadStateException will be thrown.

The following example code snippet shows a newly created a thread in the NEW state:

// Create a new thread. This thread is in NEW state.
    MyThread thread = new MyThread();
    Thread th = new Thread(thread);
        
 // Check thread state (NEW)
    System.out.println("Thread state before start: " + thread.getState());
Output: 
      Thread state before start: NEW

2. Runnable State:

Runnable state means a thread is ready for execution of any statement. When the start() method is called on a new thread, thread enters into from New to a Runnable state.


In runnable state, the thread is either running or ready to run and is waiting for the availability of the processor (CPU time) for execution of code. That is, thread has joined queue (line) of threads that are waiting for execution.

If all threads have equal priority, CPU allocates time slots for thread execution on the basis of first-come, first-serve manner. The process of allocating time to threads is known as time slicing. A thread can come into runnable state from running, waiting, or new states.

In the previous example code, let’s add t.start() method and try to access its current state:

// Create a new thread. This thread is in NEW state.
    MyThread thread = new MyThread();
    Thread th = new Thread(thread);
        
 // Check thread state (NEW)
    System.out.println("Thread state before start: " + thread.getState());
        
 // Start the thread. Now the thread moves from New to Runnable state.
    thread.start();

 // Check the current thread state after calling start.
    System.out.println("Thread state after start: " + thread.getState());
Output:
      Thread state before start: NEW
      Thread state after start: RUNNABLE

3. Running State:

Running means Processor (CPU) has allocated time slot to thread for its execution. When thread scheduler selects a thread from the runnable state for execution, it goes into running state. Look at the above figure.

Thread is in running state.

In running state, processor gives its time to the thread for execution and executes its run method. This is the state where thread performs its actual functions. A thread can come into running state only from runnable state.

The following example code shows that a thread transitions from the Runnable state to the Running state and begins executing its run() method.

public class MyThread extends Thread {
@Override
public void run() {
     System.out.println("Thread is in RUNNING state, executing run() method.");
 }
}
public class Test {
public static void main(String[] args) {
  // Create a new thread. This thread is in NEW state.
     MyThread thread = new MyThread();
     Thread th = new Thread(thread);
        
  // Check thread state (NEW)
     System.out.println("Thread state before start: " + thread.getState());
        
  // Start the thread by calling start() method. Now the thread moves from New to Runnable state.
     thread.start();

  // Check the current thread state after calling start.
     System.out.println("Thread state after start: " + thread.getState());
  }
}
Output:
      Thread state before start: NEW
      Thread state after start: RUNNABLE
      Thread is in RUNNING state, executing run() method.

This code is an example of thread’s state transitions. When start() method is called, the thread enters the Runnable state. Once the CPU schedules it, the thread transitions to the Running state, executing the run() method.

A running thread may give up its control in any one of the following situations and can enter into the blocked state.

a) When sleep() method is invoked on a thread to sleep for specified time period, the thread is out of queue during this time period. The thread again reenters into the runnable state as soon as this time period is elapsed.

b) When a thread is suspended using suspend() method for some time in order to satisfy some conditions. A suspended thread can be revived by using resume() method.

c) When wait() method is called on a thread to wait for some time. The thread in wait state can be run again using notify() or notifyAll() method.


4. Blocked State:

A thread is considered to be in the blocked state when it is suspended, sleeping, or waiting for some time in order to satisfy some condition.

For example, a thread enters the Blocked state when it is waiting to acquire a lock or a monitor that is held by another thread. This generally happens when multiple threads are trying to access a synchronized block or method.

Let’s take an example in which we will create a synchronized block where one thread holds the lock, and another thread tries to enter the synchronized block but gets blocked.

public class MyThread extends Thread {
private Object lock;

public MyThread(String name, Object lock) {
    super(name);
    this.lock = lock;
}
@Override
public void run() {
   System.out.println(Thread.currentThread().getName() + " is trying to acquire the lock.");

   synchronized (lock) {
        System.out.println(Thread.currentThread().getName() + " has acquired the lock.");
   try {
   // Hold the lock for 2 seconds.
      Thread.sleep(2000);
   } catch (InterruptedException e) {
         e.printStackTrace();
      }
      System.out.println(Thread.currentThread().getName() + " is releasing the lock.");
   }
  }
}
public class Test {
public static void main(String[] args) {
    Object lock = new Object();

 // Create two threads that will try to acquire the same lock.
    MyThread thread1 = new MyThread("Thread 1", lock);
    MyThread thread2 = new MyThread("Thread 2", lock);

 // Start both threads using start() method.
    thread1.start();
    thread2.start();
   }
}
Output:
      Thread 1 is trying to acquire the lock.
      Thread 1 has acquired the lock.
      Thread 2 is trying to acquire the lock.
      Thread 1 is releasing the lock.
      Thread 2 has acquired the lock.
      Thread 2 is releasing the lock.

In this example, we have created two threads that will try to acquire the same lock. When Thread 1 starts and enters into the synchronized block by acquiring the lock, it holds the lock for 2 seconds (Thread.sleep(2000)).

During this time, Thread 2 tries to enter the same synchronized block, but it is in the blocked state and waits for the lock to be released. This is because Thread 1 has not yet released the lock.

Once Thread 1 finishes its execution and releases the lock, Thread 2 can acquire the lock and continue its execution. Thread 2 transitions from blocked to runnable and then to running.

5. Dead or Terminated State:

A thread dies or moves into dead state automatically when its run() method completes the execution of statements. That is, a thread is terminated or dead when a thread comes out of run() method. A thread can also be dead when the stop() method is called. Once a thread is in the DEAD state, it cannot be started again.

Let’s take a simple example in which a thread entering the Dead state after it finishes executing its run() method.

public class MyThread extends Thread {
@Override
public void run() {
    System.out.println(Thread.currentThread().getName() + " is running.");

    try {
       Thread.sleep(1000);
    } catch (InterruptedException e) {
       e.printStackTrace();
      }
    System.out.println(Thread.currentThread().getName() + " has finished execution.");
  }	
}
public class Test {
public static void main(String[] args) {
    MyThread thread = new MyThread();
    thread.start();

    try {
    // Main thread waits for the created thread to finish.
       thread.join();  
    } catch (InterruptedException e) {
         e.printStackTrace();
      }
 
 // After the complete execution of thread, it goes into the dead state.
    System.out.println("Is thread alive? " + thread.isAlive());
    System.out.println("Thread has reached the Dead state.");
  }
}
Output:
      Thread-0 is running.
      Thread-0 has finished execution.
      Is thread alive? false
      Thread has reached the DEAD state.

In this example, we have created a new thread and started it using thread.start() method. The thread enters the runnable state and then goes to the running state where the run() method is executed.

Once the thread finishes the execution of run() method, it enters the dead state. Once dead, it cannot be restarted. If you try to call the start() method on the thread that is in the dead state, it will throw IllegalThreadStateException.

We have used the isAlive() method that returns false. This means that the thread is no longer active and has entered into the dead state.

During the life cycle of thread in Java, a thread moves from one state to another state in a variety of ways. This is because in multithreading environment, when multiple threads are executing, only one thread can use CPU at a time.

All other threads live in some other states, either waiting for their turn on CPU or waiting for satisfying some conditions. Therefore, a thread is always in any of the five states.


In this tutorial, you learned the life cycle of thread in Java and thread states with helpful diagrams. I hope that you will have understood the basic concepts of thread life cycle with example programs.

If you get any incorrect in this tutorial, then please inform our team through email. Your email will be precious to us. In the next, we will understand how to create threads in Java through the various examples.
Thanks for reading!!!