public final class Semaphore
{
   private int S;

   // default initial value is 0
   public Semaphore() {
      S = 0;
   }
   
   // initialization of semaphore value
   public Semaphore(int v) {
      S = v;
   }
   
   // keyword synchronized makes the method 'atomic' and mutual-exclusive 
   // only one object can access it at one time 
   public synchronized void down() {
      while (S == 0) {
         try {
            wait(); // Causes current thread to wait until another thread 
		    //  invokes the notify() method or the notifyAll() method for this object.
         }
         catch (InterruptedException e) { }
      }
      S--;          // decrement semaphore value
   }
   
   public synchronized void up() {
      S++;	    // increment semaphore value
      notify();	    // wakes up a single thread that is waiting on 
		    //  this object's monitor.
   }
}
     
