What Are the Different Thread States in Java with Code Examples?

What Are the Different Thread States in Java with Code Examples?

In Java, thread management is a critical concept for building efficient, high-performance applications. The java.lang.Thread class provides built-in support for multithreading, and understanding the Thread lifecycle is essential to effectively utilize these capabilities.

Java threads can exist in the following states as defined in the Thread.State enum:

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

Let’s explore each state with detailed explanations and code examples to bring the concept to life.


1. NEW

A thread is in the NEW state when it is created but not yet started.

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

Explanation: The thread object is instantiated, but start() has not been invoked.


2. RUNNABLE

A thread is in the RUNNABLE state after the start() method is called and before it enters the waiting or terminated states.

Thread t = new Thread(() -> {
    while(true) {
        // Simulating work
    }
});
t.start();
System.out.println(t.getState()); // Might output: RUNNABLE

Explanation: The thread is ready to run and may be executing or waiting for CPU time.


3. BLOCKED

A thread is in the BLOCKED state when it tries to access a synchronized block or method locked by another thread.

class Shared {
    synchronized void method() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {}
    }
}

Shared obj = new Shared();

Thread t1 = new Thread(() -> obj.method());
Thread t2 = new Thread(() -> obj.method());

t1.start();
t2.start();

Thread.sleep(100); // Let t1 acquire the lock
System.out.println(t2.getState()); // BLOCKED

Explanation: t2 waits for the lock held by t1.


4. WAITING

The WAITING state occurs when a thread waits indefinitely for another thread to perform a particular action.

Thread t = new Thread(() -> {
    synchronized (Thread.currentThread()) {
        try {
            Thread.currentThread().wait();
        } catch (InterruptedException e) {}
    }
});

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

Explanation: The thread waits without a timeout, requiring notify() or notifyAll() to resume.


5. TIMED_WAITING

This state is like WAITING but with a timeout.

Thread t = new Thread(() -> {
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {}
});

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

Explanation: The thread will return to RUNNABLE after 5 seconds or if interrupted.


6. TERMINATED

A thread is in the TERMINATED state when it completes execution or is aborted.

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

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

Explanation: The thread has finished its work and exited.


Visual Summary of Thread States

Here’s a quick visual of how threads transition:

  • NEWRUNNABLE
  • RUNNABLEWAITING / TIMED_WAITING / BLOCKED
  • Any → TERMINATED when the run completes or an exception is thrown

Best Practices

  • Always handle InterruptedException properly in WAITING and TIMED_WAITING states.
  • Avoid busy waiting; use proper synchronization constructs.
  • Understand thread states to debug deadlocks and performance issues.

Conclusion

Understanding thread states in Java is crucial for mastering concurrency. From the creation of a thread to its termination, Java provides a rich and well-structured model to handle thread lifecycle. Mastery of these concepts ensures better performance and fewer bugs in concurrent applications.

By understanding the transitions between NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, and TERMINATED, you can design more efficient and maintainable Java applications.

Please follow and like us:

Leave a Comment