wait() must be called while holding the monitor, and it gives that lock up until another thread calls notify() on the same object. The consumer here blocks in take() until the producer's put() flips the flag and notifies it.
class Box {
private String value;
private boolean has = false;
synchronized void put(String v) {
value = v;
has = true;
notify();
}
synchronized String take() throws InterruptedException {
while (!has) wait();
has = false;
return value;
}
}
Box box = new Box();
String[] received = new String[1];
Thread consumer = new Thread(() -> {
try {
received[0] = box.take();
} catch (InterruptedException e) { }
});
Thread producer = new Thread(() -> box.put("payload"));
consumer.start();
Thread.sleep(20);
producer.start();
producer.join();
consumer.join();
System.out.println("Consumer received: " + received[0]);
Consumer received: payload
Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.
Published 2026-09-27