Tuesday, 13 August 2013

Thread : Wait and Notify Example

In the previous chapter Synchronization we saw how multiple threads can be restricted from accessing the same block of code simultaneously. But sometimes their is a scenario where multiple threads share the same object and a communication is required between threads.
Lets take a example where John who wants to eat Ratatouille goes to a restaurant and asks for it. The chef starts creating the delicacy. But by the time the dish is done John has to wait. And john should only take the plate when chef says to john that 'I am done'.
This communication between 2 threads is possible by using wait, notify methods of Object class.
Lets simulate this in Java

public class Chef extends Thread{
 
 String plate;
 
 public void run(){
  plate="Ratatouille";
 }

}

This is a Chef class who is a Thread and just populates the plate variable after 2 sec.

public class John{
 public static void main(String[] args) {

  Chef chef = new Chef ();
  chef .start();
  
  System.out.println("Main consuming :"+chef .plate);
 }
}

John is the Main class which creates the object of Chef class and starts it. After starting the thread class it tries to consume the plate.
Lets run the program and see what happens

Main consuming :null

John was not able to consume plate because Chef was not ready with the dish i.e. it did not populate the plate variable. So we want John to wait till Chef tells I am done. Lets make some changes and see how can we fix this.

public class Chef extends Thread {

 String plate;

 public void run() {

  synchronized (this) {
   try {
    System.out.println("Chef: Prepairing Ratatouille...");
    Thread.sleep(2000);
    plate = "Ratatouille";
    System.out.println("Chef: Ratatouille prepaired, notify John");
    this.notify();
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }

 }

}
public class John {
 public static void main(String[] args) throws InterruptedException {

  Chef chef = new Chef();
  chef.start();
  synchronized (chef) {
   if (chef.plate == null) {
    System.out.println("John : Plate is empty, wait..");
    chef.wait();

   }
   System.out.println("John consuming :" + chef.plate);
  }

 }
}
John : Plate is empty, wait..
Chef: Prepairing Ratatouille...
Chef: Ratatouille prepaired, notify John
John consuming :Ratatouille
Here now John checks if plate is emty or not. John calls wait() on Chef instance variable and waits, that is it releases lock on Chef instance. Chef class now can enter the synchronized block. It calls the notify() method on the same chef object and tells john to go ahead.
Important Methods
Object.wait()

This method makes the current executing thread release the Lock on the object on which wait() was called and go into waiting state.
Object.notify()

This method makes the current executing thread release the Lock on the object on which notify() was called and wake up the Thread which has called wait() on the same object 'checf' in our case.

2 comments:

  1. Here in John class : synchronized (producer) I can not see producer object created.

    ReplyDelete
    Replies
    1. Hello Rupesh, Thank you for pointing that out. I have corrected the code.

      Delete

Share the post