Class Semaphore

java.lang.Object
EDU.oswego.cs.dl.util.concurrent.Semaphore
All Implemented Interfaces:
Sync
Direct Known Subclasses:
QueuedSemaphore, WaiterPreferenceSemaphore

public class Semaphore extends Object implements Sync
Base class for counting semaphores. Conceptually, a semaphore maintains a set of permits. Each acquire() blocks if necessary until a permit is available, and then takes it. Each release adds a permit. However, no actual permit objects are used; the Semaphore just keeps a count of the number available and acts accordingly.

A semaphore initialized to 1 can serve as a mutual exclusion lock.

Different implementation subclasses may provide different ordering guarantees (or lack thereof) surrounding which threads will be resumed upon a signal.

The default implementation makes NO guarantees about the order in which threads will acquire permits. It is often faster than other implementations.

Sample usage. Here is a class that uses a semaphore to help manage access to a pool of items.

 class Pool {
   static final MAX_AVAILABLE = 100;
   private final Semaphore available = new Semaphore(MAX_AVAILABLE);
   
   public Object getItem() throws InterruptedException { // no synch
     available.acquire();
     return getNextAvailableItem();
   }

   public void putItem(Object x) { // no synch
     if (markAsUnused(x))
       available.release();
   }

   // Not a particularly efficient data structure; just for demo

   protected Object[] items = ... whatever kinds of items being managed
   protected boolean[] used = new boolean[MAX_AVAILABLE];

   protected synchronized Object getNextAvailableItem() { 
     for (int i = 0; i invalid input: '<' MAX_AVAILABLE; ++i) {
       if (!used[i]) {
          used[i] = true;
          return items[i];
       }
     }
     return null; // not reached 
   }

   protected synchronized boolean markAsUnused(Object item) { 
     for (int i = 0; i invalid input: '<' MAX_AVAILABLE; ++i) {
       if (item == items[i]) {
          if (used[i]) {
            used[i] = false;
            return true;
          }
          else
            return false;
       }
     }
     return false;
   }

 }

[ Introduction to this package. ]

  • Field Details

    • permits_

      protected long permits_
      current number of available permits
  • Constructor Details

    • Semaphore

      public Semaphore(long initialPermits)
      Create a Semaphore with the given initial number of permits. Using a seed of one makes the semaphore act as a mutual exclusion lock. Negative seeds are also allowed, in which case no acquires will proceed until the number of releases has pushed the number of permits past 0.
  • Method Details

    • acquire

      public void acquire() throws InterruptedException
      Wait until a permit is available, and take one
      Specified by:
      acquire in interface Sync
      Throws:
      InterruptedException
    • attempt

      public boolean attempt(long msecs) throws InterruptedException
      Wait at most msecs millisconds for a permit.
      Specified by:
      attempt in interface Sync
      Parameters:
      msecs - the number of milleseconds to wait. An argument less than or equal to zero means not to wait at all. However, this may still require access to a synchronization lock, which can impose unbounded delay if there is a lot of contention among threads.
      Returns:
      true if acquired
      Throws:
      InterruptedException
    • release

      public void release()
      Release a permit
      Specified by:
      release in interface Sync
    • release

      public void release(long n)
      Release N permits. release(n) is equivalent in effect to:
         for (int i = 0; i invalid input: '<' n; ++i) release();
       

      But may be more efficient in some semaphore implementations.

      Throws:
      IllegalArgumentException - if n is negative.
    • permits

      public long permits()
      Return the current number of available permits. Returns an accurate, but possibly unstable value, that may change immediately after returning.