How can the wait()
and notify()
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()
and notify()
.
Hence, wait() and notify() methods are defined in Object class rather than Thread class. If wait() and notify() were on the Thread instead then each thread would have to know the status of every other thread and there is no way to know thread1 that thread2 was waiting for any resource to access.
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.
To guarantee liveness, programs must test the while loop condition before invoking the wait() method. This early test checks whether another thread has already satisfied the condition predicate and sent a notification. Invoking the wait() method after the notification has been sent results in indefinite blocking.
In other words, if the notify() method is called when no other thread is waiting, notify() simply returns and the notification is lost. A thread that later executes the wait() method has to wait for another notification to occur.
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 calls notify
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With