Class Semaphore

  • All Implemented Interfaces:
    Sync
    Direct Known Subclasses:
    QueuedSemaphore, WaiterPreferenceSemaphore

    public class Semaphore
    extends java.lang.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 < 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 < MAX_AVAILABLE; ++i) {
           if (item == items[i]) {
              if (used[i]) {
                used[i] = false;
                return true;
              }
              else
                return false;
           }
         }
         return false;
       }
    
     }
    

    [ Introduction to this package. ]

    • Constructor Summary

      Constructors 
      Constructor Description
      Semaphore​(long initialPermits)
      Create a Semaphore with the given initial number of permits.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void acquire()
      Wait until a permit is available, and take one
      boolean attempt​(long msecs)
      Wait at most msecs millisconds for a permit.
      long permits()
      Return the current number of available permits.
      void release()
      Release a permit
      void release​(long n)
      Release N permits.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • permits_

        protected long permits_
        current number of available permits
    • Constructor Detail

      • 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 Detail

      • acquire

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

        public boolean attempt​(long msecs)
                        throws java.lang.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:
        java.lang.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 < n; ++i) release();
         

        But may be more efficient in some semaphore implementations.

        Throws:
        java.lang.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.