java semaphore

Wikipedia semaphore concept explained as follows

Semaphore ( English: semaphore ), also known as a semaphore is a synchronization object, for holding a count value between 0 and the maximum value specified. When the thread completes a wait semaphore object ( when the wait), the counter value minus one; when the thread to complete a release semaphore object ( time release), a count is incremented. When the count value is 0, the threads waiting for the semaphore until the object is no longer successful semaphore object becomes signaled state. semaphore object is greater than the count value of 0, as signaled state; value is equal to 0, as nonsignaled state.

semaphore object is adapted to control a shared resource to support only a limited number of users, without using a busy-wait ( BUSY Waiting) method.

The concept semaphore is a Dutch computer scientist Edsger W. Dijkstra ( Edsger W. Dijkstra) invention, widely used in different operating systems in. In the system, giving each stroke a semaphore, on behalf of the current status of each stroke, uncontrolled right to travel will be forced to stop at a particular place, waiting for the arrival of the signal may proceed. If the semaphore is an arbitrary integer, commonly referred to as the count signal amount ( a Counting semaphore), or general signal amount ( General semaphore); If the semaphore is only a binary 0 or 1, referred to as a binary signal amount ( binary semaphore ). In linux system, the amount of the binary signal ( binary semaphore), also known as a mutex ( the Mutex).

********************************************************

Blog text: Semaphore Semaphore class in Java source code is as follows

package java.util.concurrent;
import java.util.Collection;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;


public class Semaphore implements java.io.Serializable {
    private static final long serialVersionUID = -3222578661600680210L;
    /** All mechanics via AbstractQueuedSynchronizer subclass */
    private final Sync sync;

    abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 1192457210091910933L;

        Sync(int permits) {
            setState(permits);
        }

        final int getPermits() {
            return getState();
        }

        final int nonfairTryAcquireShared(int acquires) {
            for (;;) {
                int available = getState();
                int remaining = available - acquires;
                if (remaining < 0 ||
                    compareAndSetState(available, remaining))
                    return remaining;
            }
        }

        protected final boolean tryReleaseShared(int releases) {
            for (;;) {
                int current = getState();
                int next = current + releases;
                if (next < current) // overflow
                    throw new Error("Maximum permit count exceeded");
                if (compareAndSetState(current, next))
                    return true;
            }
        }

        final void reducePermits(int reductions) {
            for (;;) {
                int current = getState();
                int next = current - reductions;
                if (next > current) // underflow
                    throw new Error("Permit count underflow");
                if (compareAndSetState(current, next))
                    return;
            }
        }

        final int drainPermits() {
            for (;;) {
                int current = getState();
                if (current == 0 || compareAndSetState(current, 0))
                    return current;
            }
        }
    }

    /**
     * NonFair version
     */
    static final class NonfairSync extends Sync {
        private static final long serialVersionUID = -2694183684443567898L;

        NonfairSync(int permits) {
            super(permits);
        }

        protected int tryAcquireShared(int acquires) {
            return nonfairTryAcquireShared(acquires);
        }
    }

    /**
     * Fair version
     */
    static final class FairSync extends Sync {
        private static final long serialVersionUID = 2014338818796000944L;

        FairSync(int permits) {
            super(permits);
        }

        protected int tryAcquireShared(int acquires) {
            for (;;) {
                if (hasQueuedPredecessors())
                    return -1;
                int available = getState();
                int remaining = available - acquires;
                if (remaining < 0 ||
                    compareAndSetState(available, remaining))
                    return remaining;
            }
        }
    }

    /**
     * Creates a {@code Semaphore} with the given number of
     * permits and nonfair fairness setting.
     *
     * @param permits the initial number of permits available.
     *        This value may be negative, in which case releases
     *        must occur before any acquires will be granted.
     */
    public Semaphore(int permits) {
        sync = new NonfairSync(permits);
    }

    
    public Semaphore(int permits, boolean fair) {
        sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    }

  
    public void acquire() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }

   
    public void acquireUninterruptibly() {
        sync.acquireShared(1);
    }

   
    public boolean tryAcquire() {
        return sync.nonfairTryAcquireShared(1) >= 0;
    }

    public boolean tryAcquire(long timeout, TimeUnit unit)
        throws InterruptedException {
        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
    }

  
    public void release() {
        sync.releaseShared(1);
    }

  
    public void acquire(int permits) throws InterruptedException {
        if (permits < 0) throw new IllegalArgumentException();
        sync.acquireSharedInterruptibly(permits);
    }

   
    public void acquireUninterruptibly(int permits) {
        if (permits < 0) throw new IllegalArgumentException();
        sync.acquireShared(permits);
    }

   
    public boolean tryAcquire(int permits) {
        if (permits < 0) throw new IllegalArgumentException();
        return sync.nonfairTryAcquireShared(permits) >= 0;
    }

    
    public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
        throws InterruptedException {
        if (permits < 0) throw new IllegalArgumentException();
        return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
    }

   
    public void release(int permits) {
        if (permits < 0) throw new IllegalArgumentException();
        sync.releaseShared(permits);
    }

   
    public int availablePermits() {
        return sync.getPermits();
    }

    public int drainPermits() {
        return sync.drainPermits();
    }

   
    protected void reducePermits(int reduction) {
        if (reduction < 0) throw new IllegalArgumentException();
        sync.reducePermits(reduction);
    }

  
    public boolean isFair() {
        return sync instanceof FairSync;
    }

   
    public final boolean hasQueuedThreads() {
        return sync.hasQueuedThreads();
    }

    
    public final int getQueueLength() {
        return sync.getQueueLength();
    }

   
    protected Collection<Thread> getQueuedThreads() {
        return sync.getQueuedThreads();
    }

   
    public String toString() {
        return super.toString() + "[Permits = " + sync.getPermits() + "]";
    }
}

It has two configurations, a single parameter is to construct an unfair lock a semaphore type, the first parameter is a two parameter specifies the number of signals, whether to use the second lock fair. For a detailed description See Semaphore Java Concurrency of

It's simple to use as follows

Define a semaphore object semaphore, before the thread execution () by semaphore.acquire obtain a semaphore, get permit if the signal current thread will be executed, otherwise the current thread will not be executed, then thread execution must release () release signal.

When the semaphore is initialized to 0, the semaphore can be placed in two call release (int a) with the current semaphore object.

Guess you like

Origin www.cnblogs.com/kitor/p/11334934.html