Java thread life cycle and wait/notify
Java thread life cycle and wait/notify
01.Java Thread Life Cycle — The 6 Main States
New → Runnable → Running → Blocked / Waiting / Timed Waiting → Terminated
1. New: Thread is created, but start() hasn’t been called yet.
Thread t = new Thread(() -> {});
2. Runnable: Thread is ready to run, but waiting for CPU time.
t.start(); // thread goes to Runnable state
3. Running: CPU picks the thread and runs its run() method.
4. Blocked: Thread is trying to enter a synchronized block, but another thread holds the lock.
synchronized(obj) {
// if another thread is inside this block, you are BLOCKED
}
5. Waiting / Timed Waiting: The thread is waiting for another thread to signal/notify it.
There are two kinds:
Waiting: infinite until notify()
Timed Waiting: waits for a timeout (e.g., sleep(1000))
wait() and notify() — How They Work
These are used for inter-thread communication — not locking.
wait(): Tells the thread -> “Go to sleep and release the lock. Wait for someone to notify you.”
notify(): Wakes up one thread that's waiting on the same object.
notifyAll(): Wakes up all threads waiting on the object.
Object lock = new Object();
Thread threadA = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("Thread A: waiting...");
lock.wait(); // releases lock and waits
System.out.println("Thread A: resumed!");
} catch (InterruptedException e) {}
}
});
Thread threadB = new Thread(() -> {
synchronized (lock) {
System.out.println("Thread B: notifying...");
lock.notify(); // wakes Thread A
}
});
threadA.start();
Thread.sleep(1000); // give A time to wait
threadB.start();
Output:
Thread A: waiting...
Thread B: notifying...
Thread A: resumed!
IMPORANT:
In a normal synchronized block, when Thread 1 releases the lock, Thread 2 automatically gets the lock when it's available — there is no need for notify()
How it works step-by-step:
1. Thread 1 enters:
synchronized (lock) {
// doing something
}
2. Thread 2 also wants to enter the same synchronized(lock):
It is BLOCKED (not WAITING)
It keeps checking (handled by JVM) — not busy-looping, but the JVM manages this.
3. Thread 1 finishes, exits the synchronized block — the lock is released.
4. Thread 2 is notified by JVM internals, and it enters automatically when it gets CPU time.
No wait() or notify() is needed here.
But when do we need wait() and notify()?
Only when you want to pause a thread manually and make it wait for a specific condition, like:
- Shared queue is empty
- A flag is not ready
- Waiting for some other task to complete
Comments
Post a Comment