Semaphore的实现主要依赖AbstractQueuedSynchronized,它实现了AQS的共享锁方案,即实现了tryAcquireShared与tryReleaseShared这两个方法。
Sync,继承自AbstractQueuedSynchronized,实现了非公平的tryAcquireShared方法与tryReleaseShared。
abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 1192457210091910933L; // 这是与排它锁的区别,排它锁的state默认为1. // 而共享锁的state可以自己设定,如果state<=0,那必须要执行一次tryReleaseShared 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 || // 如果remaining<0,是不会执行compareAndSetState(available, remaining)的 compareAndSetState(available, remaining)) return remaining; } } /** * 非公平模式与公平模式,对于锁的释放是一样的 */ protected final boolean tryReleaseShared(int releases) { for (;;) { int current = getState(); int next = current + releases; if (next < current) throw new Error("Maximum permit count exceeded"); if (compareAndSetState(current, next)) return true; } } /** * 这个方法与tryReleaseShared的实现几乎一模一样,除了返回类型,用来减少Permits */ final void reducePermits(int reductions) { for (;;) { int current = getState(); int next = current - reductions; if (next > current) throw new Error("Permit count underflow"); if (compareAndSetState(current, next)) return; } } /** * 将state设置为0 */ final int drainPermits() { for (;;) { int current = getState(); if (current == 0 || compareAndSetState(current, 0)) return current; } } }
NonfairSync,非公平策略,与ReentrantLock一样,直接使用Sync提供的方式。
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); } }
FairSync,公平策略,重写了tryAcquireShared
static final class FairSync extends Sync { private static final long serialVersionUID = 2014338818796000944L; FairSync(int permits) { super(permits); } // 与非公平的区别就在这里 protected int tryAcquireShared(int acquires) { for (;;) { // 如果当前线程不是队列的head,这不竞争 // 如果当前线程是队列的head,hasQueuedPredecessors返回false if (hasQueuedPredecessors()) return -1; int available = getState(); int remaining = available - acquires; if (remaining < 0 || compareAndSetState(available, remaining)) return remaining; } } }