Class 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 < 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. ]

    • 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

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