/**

 * Implementation of classical Dykstra semaphores.

 * @author Ken Williams

 */

 

public class Semaphore {

/**

 * The counter value for this counting semaphore.  The

 * value is initialized by the constructor and modified by p and v.

 */

private int counter;

 

/**

 * Constructor to create a semaphore object.

 * @param initCounter int initial value for the semaphore counter.

 */

public Semaphore(int initCounter) {

      counter = initCounter;

}

 

/**

 * The p method decrements the semaphore counter.  If the counter value

 * is zero before being decremented, the thread will be suspended until

 * another thread increments the counter with the v method.

 */

public synchronized void p() {

      try {

            if (counter == 0) {

                  wait();

            }

      } catch (InterruptedException e) {

            System.out.println("Semaphore exception");

            e.printStackTrace();

      }

      counter--;

}

 

/**

 * The p method decrements the semaphore counter.  If the counter value

 * is zero before being decremented, the thread will be suspended until

 * another thread increments the counter with the v method.

 * @param timeout long If a thread is delayed for more than the number of

 * milliseconds specified by the timeout parameter, an exception will be thrown.

 * @exception InterruptedException thrown if the thread is delayed more than

 * timeout milliseconds.

 */

public synchronized void p(long timeout) throws InterruptedException  {

      if (counter == 0) {

            wait(timeout);

      }

      counter--;

}

 

/**

 * The v method increments the semaphore counter.  If other threads are

 * suspended on this semaphore, one of them will be activated.

 */

public synchronized void v() {

      counter++;

      notify();

}

}