To begin, the wait() and notify() methods belong to the Object class in Java. This is to replaces the need to poll conditions repeatedly until they meet consensus – the problem with this is that it eats a lot of CPU resources.
So what do they do? Let’s answer that question…
What does the wait() Method do?
- Belongs to the java.lang.Objects class
- The wait() method pauses the thread
- To release the wait() there needs to be another live thread that invokes notify() or notifyAll() to unlock this thread
How can you call the wait method?
- wait()
- no args, will cause the thread to wait until notify() or notifyAll() is called
- wait(long timeout)
- One arg, this can either be released by notify() or notifyAll() or when the timeout elapses
- wait(long timeout, int nanoseconds)
- One arg, this can either be released by notify() or notifyAll() or when the timeout elapses with extra nanoseconds for precision
What does the notify() method do?
- Belongs to the java.lang.Objects class
- Used only to wake up one thread that’s waiting for an object
Here’s an example of how wait() and notify() can be used to synchronize two threads:
Code example!
wait() and notify() can be used to synchronise two threads:
class SharedObject {
private boolean ready = false;
public synchronized void setReady() {
ready = true;
notify();
}
public synchronized void waitUntilReady() {
while(!ready) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class ThreadA extends Thread {
private SharedObject sharedObject;
public ThreadA(SharedObject sharedObject) {
this.sharedObject = sharedObject;
}
public void run() {
// Do some work
// ...
// Set the shared object to "ready"
sharedObject.setReady();
}
}
class ThreadB extends Thread {
private SharedObject sharedObject;
public ThreadB(SharedObject sharedObject) {
this.sharedObject = sharedObject;
}
public void run() {
// Wait until the shared object is "ready"
sharedObject.waitUntilReady();
// Do some work
// ...
}
}
In this example, ThreadA sets the shared object to “ready” by calling the setReady() method, and ThreadB waits until the shared object is “ready” by calling the waitUntilReady() method. When ThreadA sets the shared object to “ready”, it also calls notify() on the shared object, which causes ThreadB to wake up and continue executing.
Note that using notify() will wake up only one thread waiting on the lock and using notifyAll() will wake up all the threads waiting on the lock.
Final Tip
It’s worth noting that in the example above, the wait() and notify() methods are used inside a synchronised block to ensure that only one thread can access the shared object at a time, which is necessary to prevent race conditions.
📚 Further Reading & Related Topics
If you’re exploring Java concurrency and inter-thread communication, these related articles will provide deeper insights:
• Difference Between Runnable and Callable in Java – Learn how these two interfaces handle multithreading differently, particularly when working with asynchronous tasks.
• Java 17’s Enhanced Pseudo-Random Number Generators (PRNG): A Dive into JEP 356 – While focused on randomness, this article also touches on thread safety concerns, which are crucial in concurrent programming.









Leave a comment