How to Work With wait()
, notify()
and notifyAll()
in Java?
Multithreading in java is pretty complex topic and requires a lot of attention while writing application code dealing with multiple threads accessing one/more shared resources at any given time.
Java 5, introduced some classes like BlockingQueue
and Executors
which take away some of the complexity by providing easy to use APIs. Programmers using these classes will feel a lot more confident than programmers directly handling synchronization stuff using wait()
and notify()
method calls.
I will also recommend to use these newer APIs over synchronization yourself, BUT many times we are required to do so for various reasons e.g. maintaining legacy code. A good knowledge around these methods will help you in such situation when arrived.
I am discussing some concepts around methods wait()
, notify()
and notifyAll()
.
What are wait()
, notify()
and notifyAll()
methods?
Before moving into concepts, lets note down a few very basic definitions involved for these methods.
The Object
class in Java has three final methods that allow threads to communicate about the locked status of a resource. These are :
-
wait()
:It tells the calling thread to give up the lock and go to sleep until some other thread enters the same monitor and calls notify().
The
wait()
methodreleases the lock prior to waiting
andre-acquires the lock prior to returning from the wait() method
.The
wait()
method is actually tightly integrated with the synchronization lock, using a feature not available directly from the synchronization mechanism. In other words, it is not possible for us to implement thewait()
method purely in Java: it is anative method
.General syntax for calling
wait()
method is like this:1
2
3
4
5
6
7
8synchronized( lockObject ) {
while( ! condition )
{
lockObject.wait();
}
}
-
notify()
:It wakes up one single thread that called
wait()
on the same object.It should be noted that calling
notify()
does not actually give up a lock on a resource.It tells a waiting thread that that thread can wake up.
However, the lock is not actually given up until the notifier’s synchronized block has completed.
So, if a notifier calls
notify()
on a resource but the notifier still needs to perform 10 seconds of actions on the resource within its synchronized block, the thread that had been waiting will need to wait at least another additional 10 seconds for the notifier to release the lock on the object, even thoughnotify()
had been called.General syntax for calling
notify()` method is like this:1
2
3
4
5
6
7synchronized(lockObject) {
//establish_the_condition;
lockObject.notify();
//any additional code if needed
}
-
notifyAll()
:It wakes up all the threads that called
wait()
on the same object. Thehighest priority thread
will run first in most of the situation,though not guaranteed
. Other things are same asnotify()
method above.General syntax for calling notify() method is like this:
1
2
3
4
5synchronized(lockObject) {
establish_the_condition;
lockObject.notifyAll();
}
Practice: Counting Semaphore
1 |
public class { |
For more details about Semaphore
, please read https://phoenixjiangnan.github.io/2016/04/03/java/concurrency/Java-Concurrency-Semaphore/
Practice: Blocking Queue
1 |
public class MyBlockingQueue<T> { |
Practice: Thread Pool
1 |
public class MyThreadPool { |
References:
近期评论