Java JavaScript Python C# C C++ Go Kotlin PHP Swift R Ruby TypeScript Scala SQL Perl rust VisualBasic Matlab Julia

Multithreading → Thread Lifecycle


Thread Lifecycle

The Stages of a Thread: Understanding Thread Life Cycle

Every thread in Java undergoes a well-defined sequence of states throughout its existence. This lifecycle provides a framework for understanding how threads are created, managed, and terminated within a program.

The Stages of a Thread's Life

A Java thread can exist in one of the following states at any given time: ⯁ New: This is the initial state when a thread object is first created. The thread hasn't begun execution yet and is waiting to be started. ⯁ Runnable: Once the start() method is invoked on the thread object, it transitions to the runnable state. This signifies that the thread is ready to run and is placed in a pool of threads waiting for CPU time from the operating system. ⯁ Running: When the operating system assigns the thread CPU time, it moves to the running state. This is where the thread actively executes its defined tasks within the run() method. ⯁ Blocked: A thread can enter a blocked state due to various reasons. This might occur when it attempts to acquire a lock (synchronization) on a resource that's currently held by another thread. In this state, the thread is suspended until the resource becomes available. ⯁ Waiting: Similar to the blocked state, a thread might enter a waiting state by calling methods like wait() or join(). These methods cause the thread to pause execution and wait for a specific condition to occur before continuing. Unlike the blocked state, waiting doesn't involve resource contention. ⯁ Timed Waiting: This state is similar to waiting, but with a predefined timeout period. The thread waits for a specific condition for a specified duration. If the condition isn't met within the timeout, the thread resumes execution. ⯁ Terminated: This is the final state of a thread's lifecycle. It signifies that the thread has completed its execution or has been terminated abruptly due to an exception or by calling the stop() method (which is generally discouraged due to potential concurrency issues).

Navigating the States

The transitions between these states are triggered by various events within the program and the operating system's scheduling decisions. Here's a simplified view of the transitions: New -> Runnable: Calling start() on the thread object. Runnable -> Running: Operating system assigns CPU time to the thread. Running -> Blocked/Waiting/Timed Waiting: Thread encounters a blocking condition (resource lock, waiting methods, timed wait). Blocked/Waiting/Timed Waiting -> Running: Resource becomes available, wait condition is met, or timeout occurs. Running/Blocked/Waiting/Timed Waiting -> Terminated: Thread finishes execution or encounters an exception.

Benefits of Thread states

Grasping the thread lifecycle is essential for effectively developing multithreaded applications in Java. It allows you to: Predict Thread Behavior: By understanding state transitions, you can anticipate how threads will react to different situations, leading to better program design. Debug Concurrency Issues: When issues arise in multithreaded programs, knowledge of thread states helps pinpoint where threads might be getting stuck or encountering unexpected behavior. Implement Synchronization: Understanding thread states is crucial for implementing proper synchronization mechanisms to ensure thread-safe access to shared resources and prevent race conditions.

Implementation of Thread States

In Java, We can get the current state of a thread using the Thread.getState() method. The java.lang.Thread.State class used to represent the state of a thread. These are:
public static final Thread.State NEW
It represents the starting state of a thread which is the NEW state.
public static final Thread.State RUNNABLE
It represents the runnable state.It means a thread is waiting to run.
public static final Thread.State BLOCKED
It represents the blocked state. In this state, the thread is waiting to acquire a lock.
public static final Thread.State WAITING
It represents the waiting state. A thread will go to this state when it invokes the Object.wait() method, or Thread.join() method with no timeout. A thread in the waiting state is waiting for another thread to complete its task.
public static final Thread.State TIMED_WAITING
It represents the timed waiting state. The main difference between waiting and timed waiting is the time constraint. Waiting has no time constraint, whereas timed waiting has the time constraint. A thread invoking the following method reaches the timed waiting state.
public static final Thread.State TERMINATED
It represents the final state of a thread that is terminated or dead. A terminated thread means it has completed its execution.

Basic Example

Thread lifecycle basic example in java public class Main { public static void main(String[] args) throws InterruptedException { MyThread thread = new MyThread(); System.out.println("Thread state (before start): " + thread.getState()); // New state thread.start(); System.out.println("Thread state (after start): " + thread.getState()); // Runnable state thread.sleep(3000); // Main thread sleeps for 1 second (thread might be running) System.out.println("Thread state (after some time): " + thread.getState()); // Likely Running state1 thread.join(); // Main thread waits for the other thread to finish System.out.println("Thread finished execution"); } } class MyThread extends Thread { @Override public void run() { System.out.println("Thread state is running"); for(int i=5;i>=0;i--){ System.out.println(i); } System.out.println("Thread state is waiting "); } }


Thread state (before start): NEW Thread state (after start): RUNNABLE Thread state is running 5 4 3 2 1 0 Thread state is waiting Thread state (after some time): TERMINATED Thread finished execution

Another example

Thread lifecycle example - multithreading in java class ThreadCheck extends Thread { public void run() { // try-catch block try { // moving thread t2 to the state timed waiting Thread.sleep(100); } catch (InterruptedException ie) { // handling error } System.out.println("T1 state while it invoked the method join() on thread t2 -"+ Main.t1.getState()); // try-catch block try { Thread.sleep(200); } catch (InterruptedException ie) { // handling error } System.out.println("T1 state after completing execution - " + Main.t1.getState()); } } // Main class implements the interface Runnable public class Main implements Runnable { public static Thread t1; public static Main obj; public static void main(String argvs[]) { // creating an object of Main class obj = new Main(); t1 = new Thread(obj); // thread t1 is created // The thread t1 is in the NEW state. System.out.println("T1 state after creating - " + t1.getState()); // invoking t1 with the start() method t1.start(); System.out.println("T1 state after starting using method start() - " + t1.getState()); } public void run() { // creating an object of ThreadCheck class and creating another thread t2 ThreadCheck myObj = new ThreadCheck(); Thread t2 = new Thread(myObj); // thread t2 is created and is currently in the NEW state. System.out.println("T2 state after creating - "+ t2.getState()); t2.start(); System.out.println("T2 state after starting using method start() - " + t2.getState()); // try-catch block for the smooth flow of the program try { // moving the thread t1 to the state timed waiting Thread.sleep(200); } catch (InterruptedException ie) { //handling error } System.out.println("T2 state after invoking method sleep() - "+ t2.getState() ); System.out.println("T1 state before invoking method join() - "+ t1.getState() ); // try-catch block for the smooth flow of the program try { // waiting for thread t2 to complete its execution t2.join(); } catch (InterruptedException ie) { // handling error } System.out.println("T2 state after completing execution - " + t2.getState()); } }


T1 state after creating - NEW T1 state after starting using method start() - RUNNABLE T2 state after creating - NEW T2 state after starting using method start() - RUNNABLE T1 state while it invoked the method join() on thread t2 -TIMED_WAITING T2 state after invoking method sleep() - TIMED_WAITING T1 state before invoking method join() - RUNNABLE T1 state after completing execution - WAITING T2 state after completing execution - TERMINATED