Java Notes
Complete guide to Thread Life Cycle states in Java — NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED, state transitions, and how to observe thread states programmatically.
The Six Thread States
Every thread in Java exists in one of six states defined in Thread.State enum:
State Descriptions
| State | Description | How to Enter | How to Exit |
|---|---|---|---|
| NEW | Thread created but not started | new Thread() | start() |
| RUNNABLE | Ready to run or currently running | start(), lock acquired, notify | Completes, blocks, waits |
| BLOCKED | Waiting to acquire a monitor lock | Entering synchronized block | Lock becomes available |
| WAITING | Waiting indefinitely for another thread | wait(), join(), park() | notify(), notifyAll(), thread ends |
| TIMED_WAITING | Waiting for a specified time | sleep(ms), wait(ms), join(ms) | Timeout expires or notification |
| TERMINATED | Thread has completed execution | run() returns or exception | Cannot exit (final state) |
Observing All States
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
| After creation | NEW |
| After start() | RUNNABLE |
| During sleep | TIMED_WAITING |
| During wait() | WAITING |
| After finish | TERMINATED |
| Waiter state | BLOCKED |
State Transitions in Detail
NEW → RUNNABLE (start())
Thread t = new Thread(() -> {}); // State: NEW
t.start(); // State: RUNNABLE
// Note: RUNNABLE means ready to run OR currently running
// The OS scheduler decides when it actually gets CPU timeRUNNABLE → TIMED_WAITING (sleep, wait with timeout, join with timeout)
Thread.sleep(1000); // TIMED_WAITING for 1 second
someObject.wait(5000); // TIMED_WAITING for up to 5 seconds
anotherThread.join(3000); // TIMED_WAITING for up to 3 secondsRUNNABLE → WAITING (wait, join without timeout)
synchronized (obj) {
obj.wait(); // WAITING until notify() called
}
anotherThread.join(); // WAITING until anotherThread finishes
LockSupport.park(); // WAITING until unparkedRUNNABLE → BLOCKED (trying to enter synchronized)
synchronized (alreadyLockedObject) {
// Thread is BLOCKED until lock is released by other thread
}Complete State Tracking Example
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output (approximate):
| [0250 ms] State changed: null | NEW |
| [0260 ms] State changed: NEW | RUNNABLE |
| [0285 ms] State changed: RUNNABLE | TIMED_WAITING |
| [0790 ms] State changed: TIMED_WAITING | RUNNABLE |
| [0792 ms] State changed: RUNNABLE | TIMED_WAITING |
| [1595 ms] State changed: TIMED_WAITING | RUNNABLE |
| [1610 ms] State changed: RUNNABLE | TERMINATED |
| Final state | TERMINATED |
Real-World Analogy: Thread States as a Restaurant Order
| NEW | Order placed (but kitchen hasn't started) |
| RUNNABLE | Chef is cooking your meal |
| BLOCKED | Chef needs the oven but someone else is using it |
| WAITING | Chef paused, waiting for ingredient delivery (no ETA) |
| TIMED_WAITING | Chef set a timer for 10 minutes (cooking) |
| TERMINATED | Meal is served and complete |
Checking Thread State Programmatically
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Common Mistakes
1. Confusing RUNNABLE with actually running
2. Confusing BLOCKED vs WAITING
Interview Questions
Q1: What are the different states of a thread in Java?
Answer: Six states defined in Thread.State: NEW (created, not started), RUNNABLE (ready/running), BLOCKED (waiting for monitor lock), WAITING (waiting indefinitely for notification), TIMED_WAITING (waiting with timeout), TERMINATED (completed execution).
Q2: What is the difference between BLOCKED and WAITING?
Answer: BLOCKED: thread is trying to enter a synchronized block but another thread holds the lock — it will automatically proceed when the lock is released. WAITING: thread explicitly called wait(), join(), or park() and must be notified/unparked to continue.
Q3: Can a thread go from TERMINATED back to RUNNABLE?
Answer: No. TERMINATED is a final state. Once a thread finishes execution, it cannot be restarted. Calling start() on a terminated thread throws IllegalThreadStateException.
Q4: What is the difference between WAITING and TIMED_WAITING?
Answer: WAITING waits indefinitely until explicitly notified (notify(), notifyAll()) or the target thread completes (join()). TIMED_WAITING has a timeout — it returns to RUNNABLE either when notified OR when the timeout expires, whichever comes first.
Q5: Is there a difference between RUNNABLE-ready and RUNNABLE-running?
Answer: In Java's thread model, no. Both are represented as RUNNABLE. The JVM doesn't distinguish between a thread waiting for CPU time (ready) and one currently executing (running). The OS scheduler handles this distinction transparently.
Q6: What state is a thread in during Thread.sleep()?
Answer: TIMED_WAITING. The thread is waiting for the specified time to elapse. It does NOT release any locks it holds during sleep.
Q8: What causes a thread to move from RUNNABLE to BLOCKED?
A: A thread moves to BLOCKED when it attempts to acquire an intrinsic lock (enter a synchronized block/method) that another thread currently holds. It remains BLOCKED until the lock becomes available. Only monitor locks cause BLOCKED state — ReentrantLock makes threads WAITING instead.
Q9: What is the difference between BLOCKED and WAITING states?
A: BLOCKED: thread is waiting to acquire a monitor lock (synchronized). WAITING: thread is waiting indefinitely for another thread's notification (wait(), join() without timeout, LockSupport.park()). BLOCKED is caused by lock contention; WAITING is caused by explicit coordination between threads.
Q10: Can a thread go back to NEW state after being TERMINATED?
A: No. Thread states are one-way: NEW → RUNNABLE → (BLOCKED/WAITING/TIMED_WAITING ↔ RUNNABLE) → TERMINATED. Once TERMINATED, the thread object exists but cannot be restarted. Calling start() again throws IllegalThreadStateException. Create a new Thread instance to run the task again.
Q11: What is TIMED_WAITING state?
A: A thread is in TIMED_WAITING when it's waiting with a specified timeout: Thread.sleep(ms), wait(ms), join(ms), LockSupport.parkNanos(), LockSupport.parkUntil(). The thread returns to RUNNABLE either when the timeout expires or when notified (whichever comes first).
Q12: How do you check a thread's current state programmatically?
A: Call thread.getState() which returns a Thread.State enum value: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, or TERMINATED. This is useful for monitoring, debugging, and testing. Note: the state may change by the time you use the returned value (it's a snapshot).
Continue the lesson path