FileDocCategorySizeDatePackage
Semaphore.javaAPI DocGlassfish v2 API6947Fri May 04 22:32:20 BST 2007com.sun.enterprise.util.sync

Semaphore

public class Semaphore extends Object
A Semaphore (counting Semaphore) is a concurrency control construct. It conforms to the standard acquire-release protocol. Counting Semaphores are widely used in implementation of multi-threaded bounded resource pools, collections etc.

A Semaphore maintains a set of totalPermits initialized in a constructor. Method acquire() blocks in wait till a permit becomes available and then takes it. The release() method needs to be invoked to add the permit back to the Semaphore and notify a waiting thread that a permit has become available to use. Method attemptAcquire() is the same as acquire() except it fails on time-out. It returns true or false based on whether it succeeded or failed.

This implementation of Semaphore is non-reentrant i.e. if the a thread that has a permit re-enters to acquire one more permit, it would be given another permit if available.

author
Dhiru Pandey 8/1/2000

Fields Summary
protected long
totalPermits
Denotes the total number permits available for the Semaphore object
Constructors Summary
public Semaphore(long initialPermits)
Constructs a new Semaphore Object and sets the total number of permits for the Semaphore.

param
initialPermits Sets the total number of permits for the Semaphore

    totalPermits = initialPermits;  // set the total number of permits
  
Methods Summary
public voidacquire()
This method tries to acquire a permit from the Semaphore. If all the permits are taken then the calling thread will wait till it is notified that a permit has become available

throws
InterruptedException thrown if the calling thread is interrupted during the execution of acquire()

    if (Thread.interrupted()) 
      throw new InterruptedException();
    synchronized (this) {
      try {
        while (totalPermits <= 0)
          wait();
        --totalPermits;
      } catch (InterruptedException ie) {
        notify();
        throw ie;
      }
    }
  
public booleanattemptAcquire(long waitTime)
This method is variation on the acquire() method, wherein it takes a waitTime parameter in milliseconds to decide how long to wait to get a permit. It also returns a true or false based on whether it was able to get the permit or not.

param
waitTime time to wait in milliseconds for the permit to become available
throws
InterruptedException thrown if the calling thread is interrupted during the execution of attemptAcquire()
return
true if acquire succeeded false otherwise

    if (Thread.interrupted()) 
      throw new InterruptedException();
    synchronized (this) {
      if (totalPermits > 0) {  // just like acquire
        --totalPermits;
        return true;
      } else if (waitTime <= 0) {   // avoided timed wait
        return false;
      } else {
        try {
          long startTime = System.currentTimeMillis();
          long timeToWait = waitTime;
          
          while (true) {
            wait(timeToWait);
            if (totalPermits > 0) {
              --totalPermits;
              return true;
            } else {    // now check for timeout
              long now = System.currentTimeMillis();
              timeToWait = waitTime - (now - startTime);
              if (timeToWait <= 0)
                return false;
            }
          }
        } catch (InterruptedException ie) {
          notify();
          throw ie;
        }
      }
    }
  
public synchronized voidrelease()
This method returns a permit to the Semaphore and will notify a waiting thread to go ahead and try to acquire the permit.

return
void

    ++totalPermits;
    notify();