- What is a Thread?
- Lifecycle of a Thread
- 1. NEW State
- Definition:
- Example:
- Real-Life Analogy:
- 2. RUNNABLE State
- Definition:
- Example:
- Note:
- 3. RUNNING State
- Definition:
- Example:
- Analogy:
- 4. BLOCKED State
- Definition:
- Example:
- 5. WAITING State
- Definition:
- Methods that cause this:
- Example:
- 6. TIMED_WAITING State
- Definition:
- Methods that cause this:
- Analogy:
- 7. TERMINATED (or DEAD) State
- Definition:
- Example:
- Analogy:
- Full Lifecycle Flow Diagram (Text Version)
- Complete Code Example to Observe Lifecycle Transitions
- Step-by-Step Explanation
- ThreadLifecycleDemo t = new ThreadLifecycleDemo();
- t.start();
- Inside run():
- Back in main() thread:
- t.join();
- After thread completes:
- Summary Table
- Bonus Tip: Use Thread.getState() to Monitor Threads
- Final Thoughts
In Java, multithreading allows concurrent execution of two or more parts of a program to maximize CPU utilization. A thread is the smallest unit of execution, and every thread in Java goes through several states (or stages) from its creation to completion.
Understanding the Thread Lifecycle is crucial when you’re working with multithreaded applications.
This guide will explain each lifecycle stage of a thread in Java using simple language, real-life analogies, and code examples so that even a beginner can follow along easily.
What is a Thread?
A Thread is like a worker that performs a specific task. In Java, every application has at least one thread: the main thread. When we create a new thread, it goes through several states before it finishes execution.
Lifecycle of a Thread
Java defines six states of a thread as per the Thread.State enum:
NEW -> RUNNABLE -> RUNNING -> BLOCKED / WAITING / TIMED_WAITING -> TERMINATED
Let’s now explore each state in detail.
1. NEW State
Definition:
A thread is in the NEW state when an object of the Thread class is created but the start() method has not been called yet.
Example:
Thread t = new Thread(() -> System.out.println("Hello from thread"));
At this point, t is in the NEW state.
Real-Life Analogy:
Imagine you’ve hired a worker, and he’s waiting outside your office. You haven’t given him any task yet.
2. RUNNABLE State
Definition:
When the start() method is called, the thread moves to the RUNNABLE state. It means it’s ready to run, but waiting for the CPU to assign time.
Example:
Thread t = new Thread(() -> System.out.println("Hello from thread"));
t.start(); // Now the thread is in RUNNABLE state
Note:
In older versions, “RUNNING” was included in RUNNABLE itself. But logically, it’s a transition between Runnable → Running.
3. RUNNING State
Definition:
When the thread scheduler picks a thread from the runnable pool and assigns CPU, it goes into the RUNNING state and begins executing the run() method.
Example:
This is managed by the JVM, so you can’t control exactly when the thread is running. But once CPU starts processing it, it is RUNNING.
Analogy:
The worker has been called in and started working on the task.
4. BLOCKED State
Definition:
If a thread tries to access a synchronized resource that is locked by another thread, it enters the BLOCKED state.
Example:
synchronized(obj) {
// only one thread can access this block at a time
}
If thread A is inside the block and thread B also tries to enter, thread B goes into the BLOCKED state until thread A exits.
5. WAITING State
Definition:
A thread is in WAITING state if it is waiting indefinitely for another thread to perform a specific action.
Methods that cause this:
Object.wait()Thread.join()(without timeout)
Example:
Thread t1 = new Thread(() -> {
try {
t2.join(); // t1 waits for t2 to finish
} catch (InterruptedException e) {
e.printStackTrace();
}
});
6. TIMED_WAITING State
Definition:
If a thread is waiting for a specified amount of time, it’s in the TIMED_WAITING state.
Methods that cause this:
sleep(time)join(time)wait(time)Thread.sleep(1000)— puts the thread in TIMED_WAITING for 1 second.
Analogy:
The worker is taking a break for 15 minutes (you know how long he’ll rest).
7. TERMINATED (or DEAD) State
Definition:
When the thread finishes execution (either normally or due to an exception), it enters the TERMINATED state.
Example:
Thread t = new Thread(() -> System.out.println("Done"));
t.start();
// After execution, t is TERMINATED
Analogy:
The worker has finished the task and left.
Full Lifecycle Flow Diagram (Text Version)
NEW
↓ start()
RUNNABLE
↓ (picked by scheduler)
RUNNING
↙ ↓ ↘
BLOCKED WAITING TIMED_WAITING
↓ ↓
RUNNABLE RUNNABLE
↓
TERMINATED
Complete Code Example to Observe Lifecycle Transitions
public class ThreadLifecycleDemo extends Thread {
public void run() {
System.out.println("Thread is RUNNING");
try {
Thread.sleep(2000); // TIMED_WAITING
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread is about to TERMINATE");
}
public static void main(String[] args) {
ThreadLifecycleDemo t = new ThreadLifecycleDemo();
System.out.println("Thread State after creation: " + t.getState()); // NEW
t.start();
System.out.println("Thread State after calling start(): " + t.getState()); // RUNNABLE
try {
Thread.sleep(100); // Main thread sleeps a bit to let child thread enter TIMED_WAITING
System.out.println("Thread State during sleep: " + t.getState()); // TIMED_WAITING or RUNNABLE
t.join(); // WAITING (main waits for t to finish)
System.out.println("Thread State after join: " + t.getState()); // TERMINATED
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Output
Thread State after creation: NEW
Thread is RUNNING
Thread State after calling start(): RUNNABLE
Thread State during sleep: TIMED_WAITING
Thread is about to TERMINATE
Thread State after join: TERMINATED
Step-by-Step Explanation
ThreadLifecycleDemo t = new ThreadLifecycleDemo();
- Creates a new thread object, but the thread has not started yet.
- State:
NEW
System.out.println("Thread State after creation: " + t.getState());
t.start();
- Starts the thread — it enters the RUNNABLE state.
- It may or may not begin executing immediately.
- State:
RUNNABLE
System.out.println("Thread State after calling start(): " + t.getState());
Inside run():
System.out.println("Thread is RUNNING");
Thread.sleep(2000);
- The thread begins executing and prints “Thread is RUNNING”.
- Then it calls
sleep(2000), which puts it into the TIMED_WAITING state for 2 seconds.
Back in main() thread:
Thread.sleep(100);
System.out.println("Thread State during sleep: " + t.getState());
- The main thread pauses for 100ms, during which the child thread is most likely sleeping.
- So the state of the thread should be TIMED_WAITING.
- If sleep finishes early (very unlikely in 100ms), it might be back to RUNNABLE.
t.join();
- The main thread waits for the child thread to finish using
join(). - While the main thread is waiting, it enters WAITING state (though not visible here, since we check the state of
tnotmain). - Once the child thread finishes, control resumes.
After thread completes:
System.out.println("Thread State after join: " + t.getState());
- Since the thread has completed its
run()method, it enters the TERMINATED state.
Summary Table
| State | Trigger | Meaning |
|---|---|---|
| NEW | Thread created | Not started yet |
| RUNNABLE | .start() called | Waiting for CPU |
| RUNNING | Got CPU time | Executing run() method |
| BLOCKED | Waiting for a lock | Locked resource not available |
| WAITING | .wait(), .join() | Waiting indefinitely |
| TIMED_WAITING | sleep(), wait(ms), join(ms) | Waiting for a specific time |
| TERMINATED | Execution completed | Thread is dead |
Bonus Tip: Use Thread.getState() to Monitor Threads
You can call .getState() on any thread object to find out its current lifecycle state. This is helpful during debugging multithreaded applications.
Final Thoughts
Understanding the Thread Lifecycle in Java is a foundational step toward mastering concurrency and multithreading. It helps you control, manage, and debug complex multithreaded applications.
Now that you know how threads move between different states.