Draw the life cycle of thread diagram and explain it with example.
Java Thread Life Cycle: Diagram and Example (B.Tech CSE, 5th Semester)
In Java, every thread moves through well-defined states from creation to completion. Understanding the thread life cycle helps you write correct, efficient, and thread-safe programs. Below is a clear diagram and a simple example to visualize how a thread transitions between states.
Thread Life Cycle Diagram (States and Transitions)
States in Java (java.lang.Thread.State):
NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED
ASCII Diagram:
[NEW] --start()----------------------------------------> [RUNNABLE]
| |
| CPU assigned (ready/running) |
| |
|-- cannot get monitor/lock ----------> [BLOCKED]
| |
|<-- lock acquired ---------------------|
|
|-- wait() / join() (no timeout) ----> [WAITING]
| |
|<-- notify()/notifyAll() / target ends-|
|
|-- sleep(t) / wait(t) / join(t) ----> [TIMED_WAITING]
| |
|<-- time expires ----------------------|
|
|-- run() completes ------------------> [TERMINATED]
Notes:
- RUNNABLE in Java includes both "ready" and "running" (there is no separate RUNNING state).
- BLOCKED occurs when a thread tries to enter a synchronized block but the monitor is held by another thread.
- WAITING means waiting indefinitely; TIMED_WAITING means waiting with a timeout.
States Explained in Simple Terms
- NEW: Thread object is created but
start()not called yet. - RUNNABLE: Thread is ready to run or actually running on the CPU.
- BLOCKED: Waiting to acquire a monitor/lock to enter a synchronized block/method.
- WAITING: Waiting indefinitely for another thread’s action (e.g.,
wait(),join()without timeout). - TIMED_WAITING: Paused for a specified time (e.g.,
sleep(ms),wait(ms),join(ms)). - TERMINATED: Thread’s
run()method finished (normal or due to uncaught exception).
Java Example: Observe Thread States in Action
This program creates four threads to demonstrate TIMED_WAITING, BLOCKED, and WAITING, and prints their states as they change.
// File: ThreadLifeCycleDemo.java
public class ThreadLifeCycleDemo {
static final Object LOCK = new Object();
public static void main(String[] args) throws Exception {
// 1) Will go to TIMED_WAITING via sleep()
Thread tSleep = new Thread(() -> {
try { Thread.sleep(1000); } catch (InterruptedException ignored) {}
}, "Sleeper");
// 2) Holds the LOCK for a while
Thread tLock = new Thread(() -> {
synchronized (LOCK) {
try { Thread.sleep(1200); } catch (InterruptedException ignored) {}
}
}, "LockHolder");
// 3) Tries to enter synchronized block while LockHolder holds it -> BLOCKED
Thread tBlocked = new Thread(() -> {
synchronized (LOCK) {
busyWork(300); // runs after lock becomes available
}
}, "BlockedOnLock");
// 4) WAITING: This thread waits for LockHolder to finish using join()
Thread tJoiner = new Thread(() -> {
try { tLock.join(); } catch (InterruptedException ignored) {}
}, "Joiner");
// Initial states: all NEW
System.out.println(tSleep.getName() + " -> " + tSleep.getState());
System.out.println(tLock.getName() + " -> " + tLock.getState());
System.out.println(tBlocked.getName() + " -> " + tBlocked.getState());
System.out.println(tJoiner.getName() + " -> " + tJoiner.getState());
System.out.println("--- starting threads ---");
// Start in a sequence that creates clear states
tLock.start(); // Grabs LOCK and sleeps
Thread.sleep(50); // Give LockHolder time to acquire lock
tBlocked.start(); // Will be BLOCKED on LOCK
tSleep.start(); // Will go to TIMED_WAITING (sleep)
tJoiner.start(); // Will WAIT for LockHolder to finish
// Monitor: print states periodically until all finish
Thread monitor = new Thread(() -> {
Thread[] arr = { tLock, tBlocked, tSleep, tJoiner };
boolean anyAlive;
do {
anyAlive = false;
for (Thread t : arr) {
System.out.println(t.getName() + " -> " + t.getState());
if (t.isAlive()) anyAlive = true;
}
System.out.println("---");
try { Thread.sleep(200); } catch (InterruptedException ignored) {}
} while (anyAlive);
// Final states: TERMINATED
for (Thread t : new Thread[]{tLock, tBlocked, tSleep, tJoiner}) {
System.out.println(t.getName() + " -> " + t.getState());
}
}, "Monitor");
monitor.start();
monitor.join();
}
static void busyWork(long ms) {
long end = System.currentTimeMillis() + ms;
while (System.currentTimeMillis() < end) {
// simple CPU work
}
}
}
What This Example Demonstrates
- Sleeper goes to TIMED_WAITING due to
Thread.sleep(1000). - LockHolder enters RUNNABLE then holds a monitor (inside synchronized) and sleeps.
- BlockedOnLock becomes BLOCKED until LockHolder releases the monitor.
- Joiner becomes WAITING because it called
join()on LockHolder. - All threads eventually reach TERMINATED when their
run()methods complete.
Key Takeaways for Exams
- Java defines six thread states: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED.
start()moves a thread from NEW to RUNNABLE; finishingrun()moves it to TERMINATED.synchronizedcan cause BLOCKED;wait()/join()cause WAITING;sleep()causes TIMED_WAITING.- RUNNABLE covers both ready and running; the scheduler decides when a RUNNABLE thread actually runs.
