CodeToConcept
About

java

java Tutorials

Introduction
Java Variables
Java Data Types
Java Type Casting
Java Operators
Java Input/Output
Java Class & Object
java Method
Java Constructor
Java this keyword
Java super keyword
Java Method Overloading and Overriding
Java Interface
Java Abstract Class
Java Memory Management
Design Patterns
JDBC (Database Connectivity)
Java IDEs

java Tutorials

Introduction
Java Variables
Java Data Types
Java Type Casting
Java Operators
Java Input/Output
Java Class & Object
java Method
Java Constructor
Java this keyword
Java super keyword
Java Method Overloading and Overriding
Java Interface
Java Abstract Class
Java Memory Management
Design Patterns
JDBC (Database Connectivity)
Java IDEs

Sample Question

Think it through, then check the tutorial.

CodeToConcept

Quickly learn through simple, structured, and practical coding tutorials. Build your confidence from step zero to real-world experience.

© 2026 CodeToConcept. All rights reserved.

Quick Links

AboutTutorials

Tutorials

JavaHTMLCSS

Support

Privacy PolicyTerms of ServiceContact
GitHubTwitterYouTube

Java Thread Lifecycle

A thread can be created, scheduled, blocked, waiting, or finished. Thread.State names the states Java exposes, but a state reading is only a snapshot. The examples connect these states to actions such as start(), sleep(), waiting for a lock, and completing run().

What is the Thread Lifecycle?

The thread lifecycle describes the different states a thread can be in during its lifetime.

A thread can be in one of the following six states:

  • NEW
  • RUNNABLE
  • BLOCKED
  • WAITING
  • TIMED_WAITING
  • TERMINATED

These states are defined by the Thread.State enum.

Thread Lifecycle Diagram

The basic lifecycle can be understood as:

            Thread Created
                   |
                   v
                 NEW
                   |
                start()
                   |
                   v
              RUNNABLE
              /   |   \
             /    |    \
            v     v     v
       BLOCKED  WAITING  TIMED_WAITING
            \      |       /
             \     |      /
              \    |     /
               \   |    /
                RUNNABLE
                   |
                   |
             run() completes
                   |
                   v
              TERMINATED

A thread does not necessarily move through every state. Its state depends on what the thread is doing.

1. NEW State

A thread is in the NEW state when a Thread object has been created but its start() method has not yet been called.

Example

Thread thread = new Thread(() -> {
    System.out.println("Task is running");
});

At this point, the thread has been created, but it has not started.

We can check its state:

System.out.println(thread.getState());

Output

NEW

The thread remains in the NEW state until start() is called.

2. RUNNABLE State

When start() is called, the thread moves from NEW to RUNNABLE.

thread.start();

The thread is now eligible to run.

Example

Thread thread = new Thread(() -> {
    System.out.println("Task is running");
});
 
System.out.println(thread.getState());
 
thread.start();

The state before calling start() is NEW.

After starting, the thread enters the RUNNABLE state.

What Does RUNNABLE Mean?

The RUNNABLE state means that the thread is either:

  • ready to run, or
  • currently running.

Java combines these conditions into the single RUNNABLE state.

For example, a thread may be ready to execute but waiting for CPU time from the operating system.

Therefore, Java does not have a separate RUNNING state in Thread.State.

3. BLOCKED State

A thread enters the BLOCKED state when it is waiting to acquire a monitor lock in order to enter a synchronized block or method.

Consider this example:

class Counter {
 
    public synchronized void increment() {
 
        for (int i = 0; i < 5; i++) {
            System.out.println(
                Thread.currentThread().getName()
            );
        }
    }
}

Suppose two threads try to execute the synchronized method at the same time.

Only one thread can acquire the object's monitor lock.

The other thread must wait for the lock.

That waiting thread can enter the BLOCKED state.

Conceptually:

Thread-1 → owns lock → executing
Thread-2 → waiting for lock → BLOCKED

When Thread-1 releases the lock, Thread-2 can compete for the lock and continue.

4. WAITING State

A thread enters the WAITING state when it waits indefinitely for another thread or action to occur.

Some methods that can cause a thread to enter WAITING include:

  • Object.wait()
  • Thread.join()
  • LockSupport.park()

For example:

Thread thread = new Thread(() -> {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
});
 
thread.start();
 
thread.join();

Here, the thread that calls join() waits until the specified thread finishes.

WAITING Example with wait()

A thread can also enter the WAITING state by calling wait().

synchronized (lock) {
    lock.wait();
}

The thread waits until another thread performs an appropriate notification, such as:

synchronized (lock) {
    lock.notify();
}

or:

synchronized (lock) {
    lock.notifyAll();
}

The exact behavior depends on how the threads coordinate.

5. TIMED_WAITING State

A thread enters the TIMED_WAITING state when it waits for a specified amount of time.

Common methods that can cause this state include:

  • Thread.sleep()
  • Object.wait(timeout)
  • Thread.join(timeout)
  • LockSupport.parkNanos()
  • LockSupport.parkUntil()

Example using sleep()

Thread thread = new Thread(() -> {
 
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
 
    System.out.println("Task completed");
});
 
thread.start();

While the thread is sleeping, it is in the TIMED_WAITING state.

After the specified time expires, the thread becomes eligible to run again.

WAITING vs TIMED_WAITING

The main difference is whether a time limit is specified.

WAITINGTIMED_WAITING
Waits indefinitelyWaits for a specified time
No timeoutHas a timeout
wait()wait(timeout)
join()join(timeout)
LockSupport.park()Thread.sleep()
Requires another event/action to continueCan continue automatically when the timeout expires

For example:

thread.join();

The calling thread waits until the target thread finishes.

Whereas:

thread.join(2000);

The calling thread waits for at most approximately 2 seconds, unless the target thread finishes earlier.

6. TERMINATED State

A thread enters the TERMINATED state after its execution has completed.

For example:

Thread thread = new Thread(() -> {
    System.out.println("Task completed");
});
 
thread.start();

After the run() method finishes, the thread is terminated.

We can check this using:

System.out.println(thread.getState());

The output will be:

TERMINATED

A terminated thread cannot be started again.

Complete Thread Lifecycle Example

The following example demonstrates several thread states:

public class HelloWorld {
 
    public static void main(String[] args) throws Exception {
 
        Thread thread = new Thread(() -> {
 
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
 
            System.out.println("Task completed");
        });
 
        System.out.println("Before start: "
                + thread.getState());
 
        thread.start();
 
        System.out.println("After start: "
                + thread.getState());
 
        Thread.sleep(500);
 
        System.out.println("While sleeping: "
                + thread.getState());
 
        thread.join();
 
        System.out.println("After completion: "
                + thread.getState());
    }
}

A possible output is:

Before start: NEW
After start: RUNNABLE
While sleeping: TIMED_WAITING
Task completed
After completion: TERMINATED

The exact state observed at a particular instant can vary because thread scheduling is not deterministic.

Thread State Using getState()

Java provides the getState() method to determine the current state of a thread.

Syntax:

thread.getState();

It returns a value of type Thread.State.

Example

Thread thread = new Thread(() -> {
    System.out.println("Running");
});
 
System.out.println(thread.getState());
 
thread.start();
 
System.out.println(thread.getState());

Possible output:

NEW
RUNNABLE

The state can change quickly, so the returned value represents the thread's state at the moment getState() is called.

Thread.State Enum

Java defines the thread states using the nested enum Thread.State.

The six constants are:

  • Thread.State.NEW
  • Thread.State.RUNNABLE
  • Thread.State.BLOCKED
  • Thread.State.WAITING
  • Thread.State.TIMED_WAITING
  • Thread.State.TERMINATED

Example

Thread.State state = thread.getState();
 
if (state == Thread.State.RUNNABLE) {
    System.out.println("Thread is runnable");
}

Thread Lifecycle and start()

The start() method is responsible for transitioning a newly created thread from NEW into execution.

Example

Thread thread = new Thread(() -> {
    System.out.println("Running");
});
 
System.out.println(thread.getState()); // NEW
 
thread.start();

A thread should be started using thread.start(); not thread.run();.

Calling run() directly does not start a new thread.

Thread Lifecycle and sleep()

When a running thread calls:

Thread.sleep(2000);

it enters the TIMED_WAITING state for the specified duration, subject to interruption and scheduling.

Example

Thread thread = new Thread(() -> {
 
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
});

After the waiting period ends, the thread becomes eligible to run again.

Thread Lifecycle and join()

The join() method causes the thread that calls it to wait for another thread to finish.

Example

Thread thread = new Thread(() -> {
    System.out.println("Worker thread");
});
 
thread.start();
 
thread.join();

Here, the thread that calls join() waits until thread terminates.

The important point is that join() affects the thread that calls join().

Thread Lifecycle and Synchronization

Synchronization can cause a thread to enter the BLOCKED state.

Example

class Test {
 
    synchronized void display() {
 
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

If one thread is executing display() and another thread tries to enter the same synchronized method on the same object, the second thread may become BLOCKED while waiting to acquire the object's monitor.

Important Difference Between BLOCKED and WAITING

These two states are often confused.

BLOCKED

A thread is waiting to acquire a monitor lock.

Thread
   ↓
Needs synchronized lock
   ↓
Lock unavailable
   ↓
BLOCKED

WAITING

A thread is waiting for another thread or action to perform a particular event.

Thread
   ↓
wait() / join() / park()
   ↓
WAITING

So:

BLOCKED  → waiting for a monitor lock
 
WAITING  → waiting for another thread/action

Important Difference Between RUNNABLE and RUNNING

Java does not define a separate RUNNING state.

The Thread.State enum contains:

  • NEW
  • RUNNABLE
  • BLOCKED
  • WAITING
  • TIMED_WAITING
  • TERMINATED

When a thread is actively executing or is ready to be scheduled, Java represents it using RUNNABLE.

The operating system is responsible for actual CPU scheduling.

Can a Thread Move Back to RUNNABLE?

Yes. A thread can move between several states during its lifecycle.

For example:

NEW
 ↓
RUNNABLE
 ↓
TIMED_WAITING
 ↓
RUNNABLE
 ↓
TERMINATED

Another possible sequence is:

NEW
 ↓
RUNNABLE
 ↓
BLOCKED
 ↓
RUNNABLE
 ↓
TERMINATED

A thread does not necessarily visit every state.

Thread Lifecycle Example with Multiple States

Consider:

class MyTask implements Runnable {
 
    @Override
    public void run() {
 
        try {
            System.out.println("Task started");
 
            Thread.sleep(2000);
 
            System.out.println("Task finished");
 
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args)
            throws InterruptedException {
 
        Thread thread = new Thread(new MyTask());
 
        System.out.println(
            "State: " + thread.getState()
        );
 
        thread.start();
 
        Thread.sleep(500);
 
        System.out.println(
            "State: " + thread.getState()
        );
 
        thread.join();
 
        System.out.println(
            "State: " + thread.getState()
        );
    }
}

A possible lifecycle is:

NEW
 ↓
start()
 ↓
RUNNABLE
 ↓
TIMED_WAITING
 ↓
RUNNABLE
 ↓
TERMINATED

Thread Lifecycle Summary

StateMeaning
NEWThread object created but not started
RUNNABLEThread is ready to run or running
BLOCKEDWaiting to acquire a monitor lock
WAITINGWaiting indefinitely for another thread/action
TIMED_WAITINGWaiting for a specified period
TERMINATEDThread execution has completed

Key Takeaways

  • Every Java thread has a lifecycle.
  • Java defines six thread states.
  • A newly created thread starts in the NEW state.
  • Calling start() moves the thread into the RUNNABLE state.
  • RUNNABLE represents both ready-to-run and actively running conditions.
  • BLOCKED means the thread is waiting to acquire a monitor lock.
  • WAITING means the thread is waiting indefinitely for another action.
  • TIMED_WAITING means the thread is waiting for a specified period.
  • A completed thread enters the TERMINATED state.
  • getState() can be used to check a thread's current state.
  • A thread does not necessarily pass through every state.
  • Thread state can change quickly because of scheduling.
  • A terminated thread cannot be started again.

Simple Lifecycle to Remember

            create Thread
                   ↓
                  NEW
                   ↓
                start()
                   ↓
              RUNNABLE
              ↙    ↓    ↘
         BLOCKED WAITING TIMED_WAITING

↘ ↓ ↙ RUNNABLE ↓ run() completes ↓ TERMINATED

The key idea is: The thread lifecycle describes how a thread moves from creation to execution, temporary waiting or blocking, and finally completion.

See you in next page....🙂

← Runnable InterfaceSynchronization →
← Runnable InterfaceSynchronization →