Suggested Pages

Monday, June 11, 2012

Interprocess Communication (wait/notify)

Wait/Notify


In Java there is a mechanism of inter-process communication based on these java primitives:
  • wait(): tells the calling thread to release the monitor and go to sleep until another thread enters the same monitor and calls notify().
  • notify(): wakes up the first thread that called wait( ) on the same object.
  • notifyAll(): wakes up all the threads that called wait( ) on the same object. The highest priority thread will run first.
Wait and Signal mechanism is used to avoid the bad practice to use polling mechanism. We can distinguish two different types of waiting:
  • Active Waiting: a thread, waiting for a condition to verify, makes a loop to check that condition. This loop causes an unnecessary CPU cycle consuming
  • Passive Waiting: a thread, waiting for a condition to verify, goes to sleep until a thread that has the knowledge to check that condition, wakes up the sleeping thread.
In the following code you can see three classes:
  • Monitor class that acts as a monitor. It has a state to be synchronized represented by counter variable.
  • ThreadOne class subtracts the counter of the Monitor until 8 from 100. It calls subtract() method of the monitor, that uses a call to notifyAll() in order to wake up other threads waiting for the object lock;
  • ThreadTwo waits that the value of counter reaches 8. It calls check() method of the monitor, that uses wait() to release the lock and wait a thread to wake it up.
  • .

Monitor.java
package com.simonefolinoblogspot.waitsignal;

public class Monitor {

 private int counter = 100;

 public synchronized void subtract() throws InterruptedException {
  this.counter--;
  System.out.println(this.counter);
  this.notifyAll();
 }

 public synchronized void check() throws InterruptedException {
  while (counter > 8) {
   System.out.println("current thread must wait: "+ counter);
   this.wait();
  }
  System.out.println("counter: "+ counter);
 }

 public synchronized int getCounter() {
  return counter;
 }

 public synchronized void setCounter(int counter) {
  this.counter = counter;
 }

}


ThreadOne.java

package com.simonefolinoblogspot.waitsignal;

public class ThreadOne extends Thread {

 private Monitor monitor;

 public ThreadOne(Monitor monitor) {
  this.monitor = monitor;
 }

 public void run() {
  try {
   while (monitor.getCounter()>8){
      Thread.sleep(100); 
      this.monitor.subtract();
   }
   System.out.println("threadone completed");
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }

}


ThreadTwo.java
package com.simonefolinoblogspot.waitsignal;

public class ThreadTwo extends Thread {

 private Monitor monitor;

 public ThreadTwo(Monitor monitor) {
  this.monitor = monitor;
 }

 public void run() {
  try {
   this.monitor.check();
   System.out.println("threadtwo completed");
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }

}
As you can see wait() and notify() methods must be written into synchronized methods or into synchronized blocks. The method check() uses wait() inside a loop to check the sleeping condition after the thread has been waken. When a thread receives a notifyAll(), it can't acquire the lock until the subtract() method ends. But when subtrack() method ends, the awake thread will try to re-acquire the lock.

No comments :

Post a Comment

Suggested Pages