foreach-ui logo
codeLanguages
account_treeDSA

Quick Actions

quizlock Random Quiz
trending_uplock Progress
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • quiz
Java
  • Understand the six thread states in Java
  • Learn state transitions and their triggers
  • Master thread interruption and priority
  • Know how to check and monitor thread states

Thread Lifecycle and States

A thread doesn't just run—it goes through states from creation to termination. Understanding this lifecycle is essential for debugging and using thread coordination correctly.

The Thread Lifecycle

A Java thread can be in one of six states, defined in Thread.State:

       NEW
        │
        ▼ start()
    RUNNABLE ◄──────────────────────────────┐
        │                                    │
        ├─── synchronized ───► BLOCKED ──────┤
        │                      (waiting      │
        │                       for lock)    │
        │                                    │
        ├─── wait()/join() ──► WAITING ──────┤
        │                      (indefinite)  │
        │                                    │
        ├─── sleep()/wait(t) ► TIMED_WAITING─┤
        │                      (with timeout)│
        │                                    │
        ▼ run() completes                    │
   TERMINATED ◄──────────────────────────────┘

State Descriptions

NEW

A thread that has been created but not yet started:

Thread thread = new Thread(() -> System.out.println("Hello"));
System.out.println(thread.getState());  // NEW

// Thread exists but hasn't been started
// Not consuming CPU resources

RUNNABLE

A thread that is ready to run or currently running:

Thread thread = new Thread(() -> {
    while (true) {
        // Busy work
    }
});
thread.start();
Thread.sleep(100);
System.out.println(thread.getState());  // RUNNABLE

Note: RUNNABLE includes both:

  • Ready: Waiting for CPU time
  • Running: Currently executing on a CPU

The JVM doesn't distinguish between these sub-states - both are RUNNABLE.

BLOCKED

A thread waiting to acquire a lock held by another thread:

Object lock = new Object();

Thread holder = new Thread(() -> {
    synchronized (lock) {
        try {
            Thread.sleep(5000);  // Hold lock for 5 seconds
        } catch (InterruptedException e) {}
    }
});

Thread waiter = new Thread(() -> {
    synchronized (lock) {  // Will block until holder releases
        System.out.println("Got the lock!");
    }
});

holder.start();
Thread.sleep(100);  // Let holder acquire lock
waiter.start();
Thread.sleep(100);

System.out.println(waiter.getState());  // BLOCKED

WAITING

A thread waiting indefinitely for another thread to perform an action:

Object lock = new Object();

Thread waiter = new Thread(() -> {
    synchronized (lock) {
        try {
            lock.wait();  // Wait indefinitely
        } catch (InterruptedException e) {}
    }
});

waiter.start();
Thread.sleep(100);
System.out.println(waiter.getState());  // WAITING

A thread enters WAITING by calling:

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

TIMED_WAITING

A thread waiting for a specified time:

Thread sleeper = new Thread(() -> {
    try {
        Thread.sleep(10000);  // Sleep for 10 seconds
    } catch (InterruptedException e) {}
});

sleeper.start();
Thread.sleep(100);
System.out.println(sleeper.getState());  // TIMED_WAITING

A thread enters TIMED_WAITING by calling:

  • Thread.sleep(long millis)
  • Object.wait(long timeout)
  • Thread.join(long millis)
  • LockSupport.parkNanos(long nanos)
  • LockSupport.parkUntil(long deadline)

TERMINATED

A thread that has completed execution:

Thread thread = new Thread(() -> System.out.println("Done!"));
thread.start();
thread.join();  // Wait for completion

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

A thread terminates when:

  • The run() method completes normally
  • The run() method throws an uncaught exception
  • The thread is stopped (deprecated)

State Transition Diagram

public class ThreadStateDemo {
    public static void main(String[] args) throws InterruptedException {
        Object lock = new Object();
        
        Thread thread = new Thread(() -> {
            // 1. Will enter BLOCKED waiting for lock
            synchronized (lock) {
                try {
                    // 3. Will enter WAITING
                    lock.wait();
                } catch (InterruptedException e) {}
            }
            // 4. Back to RUNNABLE, then TERMINATED
        });
        
        System.out.println("Created: " + thread.getState());  // NEW
        
        synchronized (lock) {
            thread.start();
            Thread.sleep(100);
            System.out.println("Started, waiting for lock: " + thread.getState());  // BLOCKED
        }
        
        Thread.sleep(100);
        System.out.println("Got lock, now waiting: " + thread.getState());  // WAITING
        
        synchronized (lock) {
            lock.notify();  // Wake up the thread
        }
        
        thread.join();
        System.out.println("Finished: " + thread.getState());  // TERMINATED
    }
}

Thread Methods and State Changes

Method Current State New State
new Thread() - NEW
start() NEW RUNNABLE
synchronized (lock unavailable) RUNNABLE BLOCKED
synchronized (lock acquired) BLOCKED RUNNABLE
wait() RUNNABLE WAITING
wait(timeout) RUNNABLE TIMED_WAITING
notify()/notifyAll() WAITING RUNNABLE (after getting lock)
sleep(timeout) RUNNABLE TIMED_WAITING
join() RUNNABLE WAITING
join(timeout) RUNNABLE TIMED_WAITING
run() completes RUNNABLE TERMINATED

Checking Thread State

Thread thread = new Thread(() -> { /* work */ });

// Check current state
Thread.State state = thread.getState();

// State comparisons
if (state == Thread.State.NEW) {
    thread.start();
}

if (state == Thread.State.TERMINATED) {
    System.out.println("Thread has finished");
}

// Check if alive (not NEW or TERMINATED)
if (thread.isAlive()) {
    System.out.println("Thread is running or blocked");
}

Interrupting Threads

Thread interruption is a cooperative mechanism to signal a thread should stop:

Thread worker = new Thread(() -> {
    while (!Thread.currentThread().isInterrupted()) {
        try {
            // Do some work
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // Interrupted during sleep
            System.out.println("Interrupted! Cleaning up...");
            Thread.currentThread().interrupt();  // Restore flag
            break;
        }
    }
    System.out.println("Thread exiting gracefully");
});

worker.start();
Thread.sleep(3000);  // Let it run for 3 seconds
worker.interrupt();   // Request stop
worker.join();

Interrupt Methods

Method Description
interrupt() Sets the interrupted flag; wakes sleeping/waiting threads
isInterrupted() Checks interrupted flag without clearing it
Thread.interrupted() Checks and clears interrupted flag (static method)

Thread Priority

Thread priority is a hint to the scheduler:

Thread highPriority = new Thread(task);
Thread lowPriority = new Thread(task);

highPriority.setPriority(Thread.MAX_PRIORITY);  // 10
lowPriority.setPriority(Thread.MIN_PRIORITY);   // 1

// Normal priority
Thread normal = new Thread(task);
normal.setPriority(Thread.NORM_PRIORITY);  // 5 (default)

Warning: Priority is just a hint. The OS scheduler makes final decisions. Don't rely on priority for correctness.

Best Practices

1. Prefer Interruption Over Deprecated Methods

// AVOID (deprecated, dangerous)
thread.stop();
thread.suspend();
thread.resume();

// USE (cooperative interruption)
thread.interrupt();
// Thread should check isInterrupted() and exit gracefully

2. Always Handle InterruptedException

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    // Option 1: Restore interrupt status
    Thread.currentThread().interrupt();
    
    // Option 2: Propagate the exception
    throw new RuntimeException("Interrupted", e);
    
    // NEVER just ignore it!
}

3. Check State Before Actions

// Don't assume thread state
if (thread.getState() == Thread.State.NEW) {
    thread.start();
} else if (thread.getState() == Thread.State.TERMINATED) {
    // Create a new thread - can't restart terminated thread
    thread = new Thread(task);
    thread.start();
}

Thread states: NEW (created), RUNNABLE (ready/running), BLOCKED (waiting for lock), WAITING (waiting for signal), TIMED_WAITING (waiting with timeout), TERMINATED (done). A thread can only be started once. RUNNABLE means eligible to run, not necessarily running. Use interruption for cooperative cancellation. Thread priority is a hint, not a guarantee. Never use deprecated stop/suspend/resume.

© 2026 forEach. All rights reserved.

Privacy Policy•Terms of Service