信号量是一种特殊的可重入锁,它给自己的state设置了一个余量,只有在有余量的情况下可以加锁。
源码分析
构造函数
public Semaphore(int permits) {
sync = new NonfairSync(permits);
}
在构造函数中传入一个许可证。sync是AQS的覆写,传入的许可证用于配置state值
Sync(int permits) {
setState(permits);
}
许可证用于申请和释放锁
NonfairSync - 非公平实现
Sync还有两个实现:NonfairSync和FairSync非公平和公平实现。
分别都实现了AQS的tryAcquireShared和tryReleaseShared方法
tryAcquireShared - 非阻塞申请共享锁
return nonfairTryAcquireShared(acquires);
传入的acquires是许可
nonfairTryAcquireShared - 非阻塞申请共享锁具体实现
final int nonfairTryAcquireShared(int acquires) {
for (;;) {
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
通过一个无限自旋,具体逻辑是获取当前state,预先计算申请后的许可量,如果申请后许可量<0,直接返回,否则>=0说明还能申请,则通过CAS操作设置。如果设置失败,继续自旋,直到成功申请到锁,或剩余许可不够了,就返回。通过返回值int正负判断是否成功加锁。
评论区