Thread Life Cycle in Java: A Complete Breakdown of States & Transitions

Multithreading is a cornerstone of Java’s robust performance capabilities, empowering developers to build high-performance, responsive applications. At the heart of this lies a solid understanding of the Java Thread Life Cycle—a sequence of states that each thread passes through during its existence.

In this guide, we’ll dive deep into each stage, unraveling how threads behave, transition, and terminate in a Java program.

Blogging Illustration

What Is a Thread in Java?

image

A thread is a lightweight, independent path of execution within a program. Java supports multithreading natively, allowing multiple threads to run concurrently for optimized CPU utilization. But behind the scenes, threads navigate through a well-defined life cycle governed by the Java Virtual Machine (JVM).

Understanding the Thread Life Cycle

Java threads operate through six well-defined states as outlined in the Thread.State enumeration:

  1. New
  2. Runnable
  3. Blocked
  4. Waiting
  5. Timed Waiting
  6. Terminated

Each state plays a crucial role in the thread's journey from creation to completion.

1. New State – The Birth of a Thread

When a thread is instantiated using the Thread class but not yet started, it remains in the New state.

                        Thread t = new Thread(); // Thread is in the New state
                    

At this stage, the thread is merely an object, and its execution hasn’t begun.

2. Runnable State – Ready for Execution

Once the start() method is invoked, the thread enters theRunnable state. Here, it's eligible for execution but awaits allocation of CPU time by the JVM scheduler.

                        t.start(); // Moves thread to Runnable state
                        

Although the thread is considered “running,” actual execution timing depends on the JVM and OS.

3. Blocked State – Locked Out of Resources

A thread moves to theBlocked state when it attempts to access a resource (e.g., a synchronized block) that’s already locked by another thread.

It remains blocked until the monitor lock is released, ensuring data consistency and avoiding race conditions.

4. Waiting State – Awaiting a Signal

In the Waitingstate, a thread pauses indefinitely, waiting for another thread to perform a specific action, such as sending a signal via notify() or notifyAll().

                        synchronized(obj) {
                         obj.wait(); // Thread enters Waiting state
                        }

                        

This state is crucial in thread coordination but must be handled carefully to prevent deadlocks.

5. Timed Waiting State – Pausing with a Countdown

A thread enters Timed Waitingwhen it’s waiting for a specified period. After the timeout, it automatically transitions back to Runnable, whether or not it receives a signal

Common methods leading to this state include:

                        Thread.sleep(1000); // Timed Waiting for 1 second
                        Other examples: join(time), wait(time), LockSupport.parkNanos().

                        

6. Terminated State – End of Execution

A thread reaches theTerminated (or Dead)state when it either:

  • Completes its execution naturally, or
  • Encounters an uncaught exception

Once terminated, a thread cannot be restarted.

Thread State Transitions: Visualizing the Journey

Here’s how a thread typically transitions between states:

  • New → Runnable: When start() is called.
  • Runnable → Running: When scheduled by the JVM.
  • Running → Blocked/Waiting/Timed Waiting: Based on resource availability or explicit pause
  • Blocked/Waiting/Timed Waiting → Runnable: Once the condition is resolved or timer expires
  • Running → Terminated: After execution completes or an exception occurs

Best Practices for Managing Thread States

  • Use synchronization wisely to avoid unnecessary blocking.
  • Prefer Timed Waiting over indefinite Waiting to reduce deadlock risk.
  • Monitor thread states during debugging for optimal performance tuning.

Conclusion

The Java Thread Life Cycle is fundamental to building efficient multithreaded applications. By mastering each thread state and understanding the transitions between them, developers can create more stable, responsive, and high-performance software.

Whether you're managing basic background tasks or implementing complex concurrency models, knowing how threads behave under the hood is a key skill every Java developer should master.

Placed Students

Our Clients

Partners

Uncodemy Learning Platform

Uncodemy Free Premium Features

Popular Courses