Java.Multithreading.How do wait() and notify()/notifyAll() methods work?

🔁 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):

ActionCondition 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() or notifyAll() 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 of if to guard against spurious wakeups.
This entry was posted in Без рубрики. Bookmark the permalink.