Fundamentals 12 min read

Mastering Java Thread Lifecycle: States, Transitions, and Debugging Tips

This article explains Java thread lifecycle, compares OS generic thread states with Java’s six states, shows how to query thread state via getState(), and introduces debugging tools like jstack and Arthas, helping developers master state transitions and write robust concurrent code.

Programmer DD
Programmer DD
Programmer DD
Mastering Java Thread Lifecycle: States, Transitions, and Debugging Tips

Why Understand Thread Lifecycle?

Understanding a thread's lifecycle lets you predict its behavior, avoid surprises, and write correct concurrent programs. Knowing each state and its transition points makes debugging and performance tuning much easier.

Thread Lifecycle States

Operating systems define five generic thread states. Java builds on these and adds its own nuances, resulting in six distinct states in the Thread.State enum.

Operating System Generic Thread States

Initial State

The thread object has been created in the language runtime but the underlying OS thread has not yet been allocated CPU time (e.g., new Thread()).

Runnable State

The thread is ready to run and can be scheduled by the OS. When the scheduler assigns a time slice, it moves to the Running state.

Running State

The OS has given the thread a CPU time slice; it is actively executing.

Blocked (Sleep) State

The thread called a blocking API or is waiting for a condition. It releases the CPU and stays blocked until the event occurs, then returns to Runnable.

Terminated State

The thread has finished execution or terminated due to an uncaught exception. No further state changes are possible.

Java Thread States

Java defines six states in java.lang.Thread.State:

NEW – a thread object has been created but not started.

RUNNABLE – combines the OS "runnable" and "running" states; the thread is eligible for execution.

BLOCKED – waiting to acquire a monitor lock (e.g., synchronized).

WAITING – waiting indefinitely for another thread (e.g., join(), Object.wait()).

TIMED_WAITING – waiting with a timeout (e.g., sleep(), wait(long)).

TERMINATED – the thread has completed.

How to Inspect a Thread’s State

Using Thread.getState()

The getState() method returns the current Thread.State value. Below are minimal examples for each state.

Thread thread = new Thread(() -> {});
System.out.println(thread.getState()); // NEW
thread.start();
System.out.println(thread.getState()); // RUNNABLE
Thread thread = new Thread(() -> {});
thread.start();
Thread.sleep(1000); // keep it alive
System.out.println(thread.getState()); // RUNNABLE (or BLOCKED if waiting on a lock)
public class ThreadStateTest {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            synchronized (ThreadStateTest.class) {
                while (true) {}
            }
        });
        t1.start();
        Thread.sleep(1000);
        System.out.println(t1.getState()); // BLOCKED
    }
}
Thread main = Thread.currentThread();
Thread t = new Thread(() -> {
    try { Thread.sleep(1000); } catch (InterruptedException e) {}
    System.out.println(main.getState()); // WAITING (because main is joining)
});
 t.start();
 t.join();
Thread t = new Thread(() -> {});
 t.start();
 Thread.sleep(1000);
 System.out.println(t.getState()); // TIMED_WAITING while sleeping
Thread t = new Thread(() -> {});
 t.start();
 Thread.sleep(1000);
 System.out.println(t.getState()); // TERMINATED after run method ends

jstack Command

jstack prints thread stacks, states, and lock information for a running JVM. It is useful for diagnosing deadlocks and long‑running threads.

Arthas

Arthas is an interactive Java diagnostic tool that can inspect thread stacks, states, and lock information without restarting the application.

Soul‑Searching Questions

Why call Thread.currentThread().interrupt() after catching InterruptedException from Thread.sleep?

When a thread waits on Lock.lock(), what state does it enter and why?

What are the differences between synchronized and Lock?

Answering these questions deepens your understanding of thread state transitions and helps you write more reliable concurrent code.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DebuggingJavaconcurrencyThreadLifecycleArthasjstack
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.