Friday, August 11, 2017

Theory behind wait(), notify() and notifyAll()

Multithreading in java is implemented with concept of Object and its Monitor.

Imagine monitor as a flag(or) register. JVM manages this.


If multiple threads need to access or share the object, first a thread has to acquire lock on the monitor of the object. Once a thread acquires a lock, no other thread can access that object. This can be done by using "synchronized" keyword in Java.

So far, a thread acquires a lock but how it notifies other threads to acquire a lock on the object?

wait(), notify() and notifyAll()
How it works?

Eg: Produced and Consumer Problem

A Queue object with size field is being shared by Producer and Consumer threads.

class Producer{
run()
{
synchronized(msg){
  if(msg.size =  max)
      wait();
  msg.push();
  notifyAll();
}
}
}

class Consumer{
run()
{
synchronized(msg){
  if(msg.size ==  min)
      wait();
  msg.pop();
  notifyAll();
}
}
}

class ProducerConsumerDemo(){
    public static void main(String arg){
       Queue msg = new Queue();
             msg.size = 10;

Producer p = new Producer();
Consumer c = new Consumer();

p.start();
c.start();
       

   }
}



How it works:
Lets say P acquires lock on msg first. P starts and C starts. Since, P acquired, C cant enter its synchronized block. P starts in its synchronized block. Since msg is empty at first, P push() happens. msg has one element. P calls notifyAll(). Means it exits the synchronized block and releases lock on msg. C starts and enters synchronized block. C consumer one element of msg. Now msg has zero elements. C calls notifyAll()--> Means C releases lock. C exits the synchronized block. Now, lets say C got the lock. C enters synchronized block but just waits and releases the lock. Now P enters the synchronized block. P produces. P notifies. P releases the lock. P exits the synchronized block...the story repeats.

Important derivations:
wait(): When a thread calls wait() in a synchronized block,
1) It does not leave the synchronized block
2) It releases the lock
3) It will be in wait/blocked state

When another thread notifies, it continues execution from where it started waiting. Means, line of code after wait() statement.

Notify: When a thread calls notify() in a synchronized block
1) It does not leave the synchronized block if notify() is not the last statement in synchronized block. It continues execution of statements after this. During this also, no other object acquires Lock. Another thread acquires lock, if the current thread exits synchronized block.

2) It leaves synchronized block if notify() is last statement in the synchronized block
3) It releases the lcok[ONly after exiting the synchronized block]

This thread needs to acquire lock again if it needs to execute.

sleep(): Does not release lock. It pauses main() thread.


wait
    synchronized(obj){
                     ---------
                     ---------
                     ---------
                     wait();  // At this point, thread goes to wait state.
                     ---------  // Form this point will be continued execution after notified by other threads
                     ---------
                     ---------
                     ---------

}   // Synchronized end




notifyAll
        synchronized(obj){
                     ---------
                     ---------
                     ---------
                     notifyAll(); // At this point, thread might release or might not release lock based on next 
                     [---------         lines of code exist or not.
                     ---------          If next line exist, it does not release the lock
                     ---------]         If next line does not exist, it releases the lock

} //End of synchronized block


Note: In a syncrhonized block, both wait() and notify() should exist. Or at least notify() has to exist.

No comments:

How J2EE components work together in any Container - Spring or Application Server

In a Spring+Jersey+Hibernate RESTful webapplication, we can spot various J2EE components - JTA, JPA, Java Bean Validation, JSON-B API for B...