What is a Thread

A thread is the smallest unit of execution inside a process.

  • A process = your Java application (JVM instance)
  • A thread = a path of execution inside that process

Example:

  • Your Spring Boot app → 1 process
  • Each HTTP request → handled by a separate thread

Why Threads?

Without threads:

task1();
task2();
task3();

👉 Runs sequentially (slow)

With threads:

task1 -> Thread-1
task2 -> Thread-2
task3 -> Thread-3

👉 Runs concurrently (faster, better CPU usage)


Thread Lifecycle

NEW → RUNNABLE ↔ RUNNING → (BLOCKED / WAITING / TIMED_WAITING) → TERMINATED

Important:

  • Java does NOT have a separate RUNNING state in API
  • Both ready + running = RUNNABLE

A thread state. A thread can be in one of the following states:

NEW

A thread that has not yet started is in this state.

RUNNABLE

A thread executing in the Java virtual machine is in this state.

BLOCKED

A thread that is blocked waiting for a monitor lock is in this state.

WAITING

A thread that is waiting indefinitely for another thread to perform a particular action is in this state.

TIMED_WAITING

A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.

TERMINATED

A thread that has exited is in this state. A thread can be in only one state at a given point in time. These states are virtual machine states which do not reflect any operating system thread states.


1. NEW State

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

👉 Thread created but not started

t.getState(); // NEW


2. RUNNABLE State (After start())

t.start();

What happens internally:

  • JVM calls native method → creates OS thread
  • Thread moves to RUNNABLE pool

👉 It may:

  • Run immediately OR
  • Wait for CPU

3. BLOCKED State (Waiting for Lock)

public static void main(String[] args) {
    
    Object lock = new Object();
    
    Thread t1 = new Thread(() -> {
        synchronized (lock) {
            try { Thread.sleep(3000); } catch (Exception e) {}
        }
    });
    
    Thread t2 = new Thread(() -> {
        synchronized (lock) {
            System.out.println("Got lock");
        }
    });
    
    t1.start();
    t2.start();

}

What happens:

  • t1 gets lock
  • t2 tries → goes to BLOCKED

👉 State:

t2.getState(); // BLOCKED


4. WAITING State (Indefinite Wait)

Trigger methods:

wait()

Object lock = new Object();

Thread t = new Thread(() -> {
    synchronized (lock) {
        try {
            lock.wait(); // WAITING
        } catch (Exception e) {}
    }
});

join()

Thread t1 = new Thread(() -> {
    try { Thread.sleep(2000); } catch (Exception e) {}
});

t1.start();
t1.join(); // main thread WAITING

System.out.println("Done");

👉 Main thread goes to:

WAITING


5. TIMED_WAITING State

Trigger methods:

  • sleep(ms)
  • wait(ms)
  • join(ms)
Thread t = new Thread(() -> {
    try {
        Thread.sleep(3000); // TIMED_WAITING
    } catch (Exception e) {}
});

6. TERMINATED State

When: run() method completes

Thread t = new Thread(() -> {
    System.out.println("Done");
});

t.start();
t.join();

System.out.println(t.getState()); // TERMINATED

This site uses Just the Docs, a documentation theme for Jekyll.