Semaphore和CountDownLath都是基于共享模式的实现类,在工作中也是使用比较多的工具类。工具类的实现方式我们依然先不考虑,单单从AQS本身分析。
AQS的共享方式获取同步器状态与独占方式类似。接下来就和勾勾继续学习AQS的源码知识吧。
共享模式.获取操作
acquireShared共享模式获取同步器状态,忽略中断。其源码如下:
//共享模式获取同步器状态
public final void acquireShared(int arg) {
//判断是否能在共享模式下获取锁状态,允许则返回大于0的值,不允许则返回小等于0的值
if (tryAcquireShared(arg) < 0)
//如果获取同步器失败,则通过死循环的方式不断的获取同步器状态
doAcquireShared(arg);
}
tryAcquireShared方法AQS本身没有实现,不同的子类重写各自的获取同步器状态的方法。接下来我们分析核心方法doAcquireShared。
doAcquireShared方法与独占模式下的acquireQueued方法是类似的思路,我们先分析其源码:
//共享模式下获取同步器状态
private void doAcquireShared(int arg) {
//将当前线程封装成Node对象添加至队列尾部,mode为Node.SHARED,此方法与独占模式相同
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
//获取node前驱节点
final Node p = node.predecessor();
//如果前驱节点为头节点
if (p == head) {
//判读是否能够获取同步器状态
int r = tryAcquireShared(arg);
//如果允许获取同步器状态
if (r >= 0) {