Semaphore的作用是,限制线程通行的数量,如果线程进入时达到通行数量,便等待其它正在通行的线程释放。
- acquire()
获取通行 - release()
释放通行 - availablePermits()
查看通行剩余次数 - int drainPermits()
缩减剩余通行次数为0,并返回缩减量 - reducePermits(int)
缩减通行次数为指定次数 - boolean isFair()
查看是否公平分配通行 - boolean hasQueuedThreads()
查看是否有线程在排队 - int getQueueLength()
查看排队的长度 - Collection<Thread> getQueuedThreads()
查看排队中的所有线程
源码:
/** * @since 1.5 * @author Doug Lea */ public class Semaphore implements java.io.Serializable { private static final long serialVersionUID = -3222578661600680210L; private final Sync sync; public Semaphore(int permits) { // 默认使用非公平锁,设置初始的剩余通行量 sync = new NonfairSync(permits); } public Semaphore(int permits, boolean fair) { // 参数决定使用公平还是非公平锁,设置初始的剩余通行量 sync = fair ? new FairSync(permits) : new NonfairSync(permits); } 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; // 设置获取后的剩余通行量 // 当剩余量小于0时,则阻塞,否则通行 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(); // 直接把剩余通行量设置为0 if (current == 0 || compareAndSetState(current, 0)) return current; } } } 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); } } 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; // 设置获取后的剩余通行量 // 当剩余量小0时,则阻塞,否则通行 if (remaining < 0 || compareAndSetState(available, remaining)) return remaining; } } } 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 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() { // 释放一次通行 sync.releaseShared(1); } public void release(int permits) { if (permits < 0) throw new IllegalArgumentException(); // 释放指定的通行次数 sync.releaseShared(permits); } public int availablePermits() { // 返回剩余的通行量 return sync.getPermits(); } public int drainPermits() { // 直接把通行量设置为0 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() + "]"; } }