Multithreading enables performance and responsiveness, but coordination between threads is critical. Java provides wait(), notify(), and notifyAll() as native methods to facilitate thread communication.
This tutorial unpacks how these methods work, when to use them, and how to avoid concurrency pitfalls in Java applications.
๐งต What is Thread Communication?
Thread communication in Java allows threads to cooperate over shared data, avoiding race conditions and unnecessary CPU cycles from busy waiting.
Real-world Analogy
Think of a delivery system: a producer thread (sender) prepares a parcel and puts it in a dropbox. A consumer thread (delivery boy) waits until there is a parcel. The consumer sleeps (wait()), and the producer wakes it up (notify()) once the parcel is ready.
๐ฆ Thread Lifecycle Overview
Java threads move between the following states:
- NEW โ RUNNABLE โ RUNNING โ WAITING/BLOCKED โ TERMINATED
The wait() method transitions the thread to the WAITING state, pausing its execution.
๐ Core Thread Communication Methods
wait()
- Causes the current thread to release the monitor and go into waiting state.
- Only resumes when
notify()ornotifyAll()is called. - Must be used inside a synchronized block.
notify()
- Wakes one waiting thread on the object's monitor.
notifyAll()
- Wakes all threads waiting on the object's monitor.
synchronized (sharedLock) {
while (!conditionMet) {
sharedLock.wait();
}
// Do work once condition is true
}
synchronized (sharedLock) {
conditionMet = true;
sharedLock.notify(); // or notifyAll()
}
โ ๏ธ Key Rules to Remember
- All methods must be called within synchronized blocks.
- Always use
wait()inside awhileloop, notif, to prevent spurious wakeups. notify()randomly picks one thread;notifyAll()wakes all.
๐ทโโ๏ธ Producer-Consumer Example
class Buffer {
private boolean full = false;
synchronized void produce() throws InterruptedException {
while (full) wait();
System.out.println("Produced item");
full = true;
notify();
}
synchronized void consume() throws InterruptedException {
while (!full) wait();
System.out.println("Consumed item");
full = false;
notify();
}
}
๐ wait/notify vs Modern Alternatives
| Goal | Preferred Tool |
|---|---|
| Thread coordination | wait(), notify(), notifyAll() |
| Producer-consumer | BlockingQueue |
| Task completion | Future, CompletableFuture |
| Scheduling | Executors, ForkJoinPool |
๐ What's New in Java Concurrency (8โ21)
- Java 8: Lambdas,
CompletableFuture, parallel streams - Java 9: Flow API for reactive programming
- Java 11: Minor improvements in
CompletableFuture - Java 21: Structured concurrency, virtual threads, scoped values (Project Loom)
๐ Best Practices
- Keep synchronized sections short and efficient.
- Avoid calling wait/notify on
thisunless it's safe. - Prefer higher-level constructs like
BlockingQueuewhen applicable. - Ensure proper lock release using try-finally blocks.
โ FAQ
-
Can
wait()be used outsidesynchronized?
No. It throwsIllegalMonitorStateException. -
Why use
whileinstead ofifwithwait()?
To protect against spurious wakeups. -
Is
notify()guaranteed to wake the right thread?
No, it's non-deterministic.notifyAll()is safer. -
What is a spurious wakeup?
When a thread wakes without being notified. -
How is
join()different fromwait()?join()waits for thread completion, not for condition. -
Can I use
notify()withoutwait()?
Yes, but it does nothing if no thread is waiting. -
What happens if a thread is never notified?
It remains in WAITING state indefinitely (potential deadlock). -
Should I use
notifyAll()always?
Use it when multiple waiting threads need rechecking. -
Are
wait()andnotify()deprecated?
No, but newer constructs often provide better abstraction. -
What is the monitor object?
It's the object whose lock is acquired in asynchronizedblock.
๐งพ Conclusion and Key Takeaways
wait(),notify(), andnotifyAll()are essential for low-level thread coordination.- Always use them with synchronization and within loops.
- In modern Java, consider high-level alternatives when available.
- Understanding these core tools is key for writing responsive and correct concurrent applications.