How can the wait() and notify() methods be called on Objects that are not threads?
Solution 1
Locking is about protecting shared data.
The lock is on the data structure being protected. The threads are the things accessing the data structure. The locks are on the data structure object in order to keep the threads from accessing the data structure in an unsafe way.
Any object can be used as an intrinsic lock (meaning used in conjunction with synchronized
). This way you can guard access to any object by adding the synchronized modifier to the methods that access the shared data.
The wait
and notify
methods are called on objects that are being used as locks. The lock is a shared communication point:
When a thread that has a lock calls
notifyAll
on it, the other threads waiting on that same lock get notified. When a thread that has a lock callsnotify
on it, one of the threads waiting on that same lock gets notified.When a thread that has a lock calls
wait
on it, the thread releases the lock and goes dormant until either a) it receives a notification, or b) it just wakes up arbitrarily (the "spurious wakeup"); the waiting thread remains stuck in the call to wait until it wakes up due to one of these 2 reasons, then the thread has to re-acquire the lock before it can exit the wait method.
See the Oracle tutorial on guarded blocks, the Drop class is the shared data structure, threads using the Producer and Consumer runnables are accessing it. Locking on the Drop object controls how the threads access the Drop object's data.
Threads get used as locks in the JVM implementation, application developers are advised to avoid using threads as locks. For instance, the documentation for Thread.join says:
This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Java 5 introduced explicit locks implementing java.util.concurrent.locks.Lock
. These are more flexible than the implicit locks; there are methods analogous to wait and notify (await and signal), but they are on the Condition, not on the lock. Having multiple conditions makes it possible to target only those threads waiting for a particular type of notification.
Solution 2
You can use wait()
and notify()
to synchronize your logic. As an example
synchronized (lock) {
lock.wait(); // Will block until lock.notify() is called on another thread.
}
// Somewhere else...
...
synchronized (lock) {
lock.notify(); // Will wake up lock.wait()
}
with lock
being the class member Object lock = new Object();
Solution 3
Think using a real life example, a washroom. When you want to use the washroom at your office, you have two options to make sure no one else will come to the washroom once you are using it.
- Lock the washroom door, so everyone else will know that it's used by someone else when they try to open the door
- Go to each person in the office, lock them to their chairs (or table, or whatever), go to washroom.
Which option would you take?
Yes, it's the same in the Javaland!.
So in the above story,
- Washroom = Object you want to lock (that only you need to use)
- Your staff colleagues = other threads that you want to keep out
So just like in real life, when you have some private business, you lock that object. And when you are done with that object, you let go of the lock!.
(Yes yes!, this is a very simple description on what happens. Of course the real concept is slightly different from this, but this is a starting point)
Solution 4
You can stop your thread for time as you want using static Thread
class method sleep()
.
public class Main {
//some code here
//Thre thread will sleep for 5sec.
Thread.sleep(5000);
}
If you want to stop some objects you need to call this method's within syncronized
blocks.
public class Main {
//some code
public void waitObject(Object object) throws InterruptedException {
synchronized(object) {
object.wait();
}
}
public void notifyObject(Object object) throws InterruptedException {
synchronized(object) {
object.notify();
}
}
}
P.S. I'm sory if I wrong understand your question (English is not my native)
Solution 5
When you put some code inside synchronized block:
sychronized(lock){...}
a thread wanting to perform whatever is inside this block first acquires a lock on an object and only one thread at a time can execute the code locked on the same object. Any object can be used as a lock but you should be careful to choose the object relevant to the scope. For example when you have multiple threads adding something to the account and they all have some code responsible for that inside a block like:
sychronized(this){...}
then no synchronization takes place because they all locked on different object. Instead you should use an account object as the lock. Now consider that these threads have also method for withdrawing from an account. In this case a situation may occur where a thread wanting to withdraw something encounters an empty account. It should wait until there's some money and release the lock to other threads to avoid a deadlock. That's what wait and notify methods are for. In this example a thread that encounters an empty account releases the lock and waits for the signal from some thread that makes the deposit:
while(balance < amountToWithdraw){
lock.wait();
}
When other thread deposits some money, it signals other threads waiting on the same lock. (of course, code responsible for making deposits and withdrawals has to be synchronized on the same lock for this to work and to prevent data corruption).
balance += amountToDeposit;
lock.signallAll;
As you see the methods wait and notify only make sense inside synchronized blocks or methods.

Alexander Mills
Dev, Devops, soccer coach. https://www.github.com/oresoftware
Updated on March 09, 2021Comments
-
Alexander Mills almost 2 years
How can the
wait()
andnotify()
methods be called on Objects that are not Threads? That doesn't really make sense, does it?Surely, it must make sense, however, because the two methods are available for all Java objects. Can someone provide an explanation? I am having trouble understanding how to communicate between threads using
wait()
andnotify()
. -
Christian Bongiorno over 9 yearsA simple use of this sort of thing is a message producer/consumer Where consumer.wait(); until producer.notify();
-
Alexander Mills over 9 yearsthanks, I like this explanation: javamex.com/tutorials/wait_notify_how_to.shtml
-
Alexander Mills over 9 yearsI think this is one of the best examples: javamex.com/tutorials/wait_notify_how_to.shtml
-
Rahul Singh almost 6 yearsThanks for the explanation, I have one question why the design is like wait, notify and notifyAll are methods available for every class as every class has parent class as object class , why it was not like to have interface the way it is for cloneable interface we need to override clone method?
-
Nathan Hughes almost 6 years@Rahul: no idea, but remember java was originally designed to be about mobile code on small devices. Threading was supposed to be made easy, but they weren't thinking about highly concurrent server applications.
-
abksrv over 5 years@NathanHughes "Not that it's a good idea, because that allows any thread that can access the object to acquire its lock, even if it's not calling any methods on it; it's better to keep the lock as a private member of the data structure being locked, so that access to it is limited." Please make it clearer.
-
Nathan Hughes over 5 years@abksrv: there's a separate question that specifically addresses that; see if stackoverflow/q/442564 is clearer
-
abksrv over 5 years@NathanHughes Seems like the link is broken!
-
Nathan Hughes over 5 years@abksrv avoid synchronized this
-
shinzou almost 5 yearsIsn't this basically a lock?