🔁 wait()
, notify()
, notifyAll()
— Overview
These methods are used for thread communication: they allow threads to coordinate and cooperate by pausing and resuming execution based on certain conditions.
They are methods of java.lang.Object
, not Thread
— because every object in Java can act as a monitor (mutex/lock).
🔑 Rules (Very Important):
Action | Condition Required |
---|---|
wait() | Must hold the object’s monitor (i.e., be inside synchronized(lock) ) |
notify() | Must hold the object’s monitor |
notifyAll() | Must hold the object’s monitor |
If not — 🔥 IllegalMonitorStateException
is thrown.
🧠 What do they do?
📌 wait()
- Causes the current thread to:
- Release the monitor (lock)
- Enter waiting state
- Wait until another thread calls
notify()
ornotifyAll()
on the same object
- After being notified, it goes back to waiting to re-acquire the lock before resuming
📌 notify()
- Wakes up one waiting thread (chosen arbitrarily) that’s waiting on the same object’s monitor
📌 notifyAll()
- Wakes up all threads waiting on the same object
- Only one will get the lock first, others will keep waiting
👨💻 Simple Example:
public class ProducerConsumerExample {
public static void main(String[] args) {
SharedResource resource = new SharedResource();
Thread producer = new Thread(() -> {
try {
while (true) {
resource.produce();
Thread.sleep(1000); // simulate time to produce
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread consumer = new Thread(() -> {
try {
while (true) {
resource.consume();
Thread.sleep(1500); // simulate time to consume
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
producer.start();
consumer.start();
}
}
class SharedResource {
private boolean needProduce = true;
private int item = 0;
public synchronized void produce() throws InterruptedException {
while (!needProduce) {
wait(); // wait until the consumer consumes the item
}
item++;
System.out.println("Produced: " + item);
needProduce = false; // mark that item is now available
notify(); // notify consumer
}
public synchronized void consume() throws InterruptedException {
while (needProduce) {
wait(); // wait until producer has produced something
}
System.out.println("Consumed: " + item);
needProduce = true; // mark that we need a new item
notify(); // notify producer
}
}
🔄 Explanation:
wait()
puts the thread to sleep and releases the lock.notify()
wakes another thread, but that thread must re-acquire the lock before proceeding.while
is used instead ofif
to guard against spurious wakeups.