code
class SharedResource {
synchronized void waitForSignal() throws InterruptedException {
System.out.println("Waiting...");
wait(); // Thread will wait until notified
System.out.println("Got signal!");
}
synchronized void sendSignal() {
notify(); // Notifies one waiting thread
System.out.println("Signal sent!");
}
}
public class WaitNotifyExample {
public static void main(String[] args) {
SharedResource resource = new SharedResource();
// Thread 1: Calls waitForSignal() and waits
new Thread(() -> {
try {
resource.waitForSignal();
} catch (InterruptedException e) { }
}).start();
// Thread 2: Calls sendSignal() after 1 second
new Thread(() -> {
try {
Thread.sleep(1000);
resource.sendSignal();
} catch (InterruptedException e) { }
}).start();
}
}
Step-by-Step Execution
- Thread 1 (
waitForSignal()
) starts first- Prints “Waiting…”.
- Calls
wait()
, which releases the lock onresource
and goes into waiting state.
- Thread 2 (
sendSignal()
) starts after 1 second- Calls
sendSignal()
, acquires the lock, and callsnotify()
, which wakes up Thread 1. - Prints “Signal sent!”.
- Releases the lock.
- Calls
- Thread 1 resumes execution
- Continues after
wait()
. - Prints “Got signal!”.
- Continues after
Expected Output
Waiting...
Signal sent!
Got signal!
Explanation of Output
Event | Thread | Output Printed |
---|---|---|
Thread 1 starts and calls wait() | Thread 1 | Waiting... |
Thread 2 starts after 1 second, calls notify() | Thread 2 | Signal sent! |
Thread 1 resumes after being notified | Thread 1 | Got signal! |
✅ Order of execution is guaranteed because:
Thread 1
must print “Waiting…” before it goes into waiting.Thread 2
must print “Signal sent!” after it wakes upThread 1
.Thread 1
then resumes and prints “Got signal!”.
What Happens If We Don’t Use Thread.sleep(1000)
?
If we remove the delay from Thread 2, the execution order may change depending on thread scheduling, but the logical order remains the same.
Would you like to modify this example to use notifyAll()
instead of notify()
? 🚀
What Happens When Multiple Threads Are Waiting on notify()
?
When you have multiple threads waiting on an object’s wait()
method and only one thread calls notify()
, only one of the waiting threads is randomly chosen to wake up.
Example: Three Threads Waiting on notify()
class SharedResource {
synchronized void waitForSignal() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " is Waiting...");
wait(); // Thread goes into waiting state
System.out.println(Thread.currentThread().getName() + " Got signal!");
}
synchronized void sendSignal() {
notify(); // Notifies only ONE waiting thread
System.out.println("Signal sent by " + Thread.currentThread().getName());
}
}
public class NotifyExample {
public static void main(String[] args) {
SharedResource resource = new SharedResource();
// Three threads waiting for a signal
Thread t1 = new Thread(() -> {
try { resource.waitForSignal(); } catch (InterruptedException e) {}
}, "Thread-1");
Thread t2 = new Thread(() -> {
try { resource.waitForSignal(); } catch (InterruptedException e) {}
}, "Thread-2");
Thread t3 = new Thread(() -> {
try { resource.waitForSignal(); } catch (InterruptedException e) {}
}, "Thread-3");
// Start all waiting threads
t1.start();
t2.start();
t3.start();
// Sleep to ensure all threads are waiting before sending a signal
try { Thread.sleep(1000); } catch (InterruptedException e) {}
// One thread will be notified
new Thread(() -> resource.sendSignal(), "Notifier").start();
}
}
Expected Output (Order May Vary)
Thread-1 is Waiting...
Thread-2 is Waiting...
Thread-3 is Waiting...
Signal sent by Notifier
Thread-2 Got signal!
🛑 Only one thread (e.g., Thread-2
) is notified, while the others remain waiting.
Which Thread Receives the Signal?
notify()
wakes up only ONE thread randomly from the waiting queue.- The choice of which thread wakes up is NOT predictable (depends on JVM scheduling).
If You Want to Wake Up All Waiting Threads
- Use
notifyAll()
instead ofnotify()
. - This wakes up all waiting threads, but they still need to compete for the lock.
✅ Example Using notifyAll()
synchronized void sendSignal() {
notifyAll(); // Wakes up ALL waiting threads
System.out.println("All threads notified by " + Thread.currentThread().getName());
}
✅ Expected Output of notifyAll()
Thread-1 is Waiting...
Thread-2 is Waiting...
Thread-3 is Waiting...
All threads notified by Notifier
Thread-1 Got signal!
Thread-2 Got signal!
Thread-3 Got signal!
📌 Note: Even though all threads wake up, only one thread can proceed at a time because of the synchronized block.
Summary
Method | Effect |
---|---|
notify() | Wakes up only one waiting thread (chosen randomly). |
notifyAll() | Wakes up all waiting threads, but they still compete for the lock. |