Semaphore底层是基于AbstractQeuedSynchronizer来实现的所以Semaphore的数据结构也是依托于AQS的数据结构
1.1 Sync源码解析
/**
* 内部类Sync继承自AQS
*/
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或者CAS设置状态成功
if (remaining < 0 ||
compareAndSetState(available, remaining))
//返回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");
//如果cas成功
if (compareAndSetState(current, next))
//返回true
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");
//cas成功
if (compareAndSetState(current, next))
return;
}
}
//获取并返回所有许可
final int drainPermits() {
for (;;) {
//获取许可数
int current = getState();
//如果current等于0或者cas成功
if (current == 0 || compareAndSetState(current, 0))
return current;
}
}
}
1.2 NonfairSync源码解析
NonfairSync类继承自Sync类,表示采用非公平策略获取资源,其中有一个tryAcquireShared方法,重写AQS的tryAcquireShared方法:
/**
* 非公平版本
*/
static final class NonfairSync extends Sync {
private static final long serialVersionUID = -2694183684443567898L;
NonfairSync(int permits) {
super(permits);
}
//共享模式下获取资源
protected int tryAcquireShared(int acquires) {
//调用父类Sync中的NonfairSyncTryAcquireShared方法
return nonfairTryAcquireShared(acquires);
}
}
1.3 FairSync 源码解析
FairSync 类继承了Sync类,表示采用公平策略获取资源,其中只有一个tryAcquireShared方法,重写了AQS的tryAcquireShared:
static final class FairSync extends Sync {
private static final long serialVersionUID = 2014338818796000944L;
FairSync(int permits) {
super(permits);
}
//共享模式下获取资源
protected int tryAcquireShared(int acquires) {
for (;;) {
//同步队列存在比当前线程等待更久的结点
//如果存在则返回-1
if (hasQueuedPredecessors())
return -1;
//获取state状态
int available = getState();
//剩余时间
int remaining = available - acquires;
//如果剩余许可小于0或者cas成功
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
}
Semaphore类的非公平模式获取许可源码解析
public void acquire() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
public void acquire(int permits) throws InterruptedException {
if (permits < 0) throw new IllegalArgumentException();
sync.acquireSharedInterruptibly(permits);
}
acquire调用父类AQS中的AcquireSharedinterruptbly方法
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
//如果线程被中断
if (Thread.interrupted())
throw new InterruptedException();
//tryAcquireShared方法需要子类实现
//如果tryAcquireShared方法返回小于0
//则获取资源失败
if (tryAcquireShared(arg) < 0)
//调用doAcquireSharedInterruptibly方法
doAcquireSharedInterruptibly(arg);
}
AcquireSharedinterruptbly方法调用的tryAcquireShared方法在非公平模式下的实现如下
protected int tryAcquireShared(int arg) {
throw new UnsupportedOperationException();
}
tryAcquireShared方法调用的NonfairTryAcquireShared方法如下:详细参考: Sync源码解析
final int nonfairTryAcquireShared(int acquires) {
for (;;) {
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
tryAcquireShared方法返回小于0,则获取资源失败,执行doAcquireSharedInterruptibly方法
private void doAcquireSharedInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head) {
int r = tryAcquireShared(arg);
if (r >= 0) {
setHeadAndPropagate(node, r);
p.next = null; // help GC
failed = false;
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}
非公平模式释放许可资源源码解析
释放许可
public void release() {
sync.releaseShared(1);
}
public void release(int permits) {
if (permits < 0) throw new IllegalArgumentException();
sync.releaseShared(permits);
}
release方法调用AQS中的releaseShared方法
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
其中tryReleaseShared需要子类实现
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;
}
}
如果tryReleaseShared返回true将执行都releaseShared方法
private void doReleaseShared() {
for (;;) {
Node h = head;
if (h != null && h != tail) {
int ws = h.waitStatus;
if (ws == Node.SIGNAL) {
if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
continue; // loop to recheck cases
unparkSuccessor(h);
}
else if (ws == 0 &&
!compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
continue; // loop on failed CAS
}
if (h == head) // loop if head changed
break;
}
}
公平模式获取许可源码分析
公平模式获取许可的acquire方法与非公平模式下获取许可是一样的,不同的是tryAcquireShared方法的实现;与非公平模式相比,公平模式多了hasQueuedPredecessors。
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;
}
}
}
public final boolean hasQueuedPredecessors() {
// The correctness of this depends on head being initialized
// before tail and on head.next being accurate if the current
// thread is first in queue.
Node t = tail; // Read fields in reverse initialization order
Node h = head;
Node s;
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}
公平模式释放许可和非公平模式是一样的