Monday 13 February 2017

Why wait(), notify(), notifyAll() must be called inside a synchronized method/block

We use wait(), notify(), or notifyAll() method mostly for inter-thread communication in Java. One thread is waiting after checking a condi... thumbnail 1 summary
We use wait(), notify(), or notifyAll() method mostly for inter-thread communication in Java.
One thread is waiting after checking a condition e.g. In the classic Producer-Consumer problem, the Producer thread waits if the buffer is full and Consumer thread notify Producer thread after it creates a space in the buffer by consuming an element.

Calling notify() or notifyAll() methods issues a notification to a single or multiple thread that a condition has changed and once notification thread leaves synchronized block, all the threads which are waiting fight for object lock on which they are waiting and lucky thread returns from wait() method after reacquiring the lock and proceed further.

Let's understand the problem with an example :
One thread read data from a buffer and one thread write data into buffer. The reading data thread needs to wait until the writing data thread completly write a block data into the buffer. The wirting data thread needs to wait until the reading data thread completly read the data from the buffer. If wait(), notify(), and notifyAll() methods can be called by a ordinary method , the reading thread calls wait() and the thread is being added to waiting queue . At just the same moment, the writing thread calls notify() to signal the condition changes.So due to Race Condition the reading thread misses the change and waits forever.

Now let's think how does this potential race condition get resolved? This race condition is resolved by using synchronized keyword and locking provided by Java. In order to call the wait (), notify () or notifyAll () methods in Java, we must have obtained the lock for the object on which we're calling the method.

Since the wait() method in Java also releases the lock prior to waiting and reacquires the lock prior to returning from the wait() method, we must use this lock to ensure that checking the condition (reading is complete or not) and setting the condition (you can write) is atomic which can be achieved by using synchronized method or block in Java.

Note : We call wait (), notify () or notifyAll method in Java from synchronized method or synchronized block in Java to avoid:

1) IllegalMonitorStateException in Java which will occur if we don't call wait (), notify () or notifyAll () method from synchronized context.

2) Any potential race condition between wait and notify method in Java.

No comments

Post a Comment