Java之AbstractQueuedSynchronizer(AQS)

多线程在并发过程中发生竞争时,其实都满足以下语义:

当共有状态(state)满足某种条件时,线程执行;若不满足,则排队(queue)等待(park),直到被唤醒(unpark)
或者换一种表述:
当线程获取锁时,则继续执行;否则排队(queue)等待(park),直到被唤醒(unpark)

AQS实际上就是对上述基本语义的包装实现。

在不同的上下文中,满足状态的条件可能是不一样的,因此要由子类去实现;而排队等待包括等待后的唤醒行为应该都是相同的,所以这一部分已经由AQS实现完毕。


AQS中定义了state变量来表示共有状态,子类需要从该变量获取共有状态当前的值。

private volatile int state;
protected final int getState() { return state; }
protected final void setState(int newState) { state = newState; }

需要子类去实现的方法重要的有如下几个,比如第一个方法,若满足状态(获得了锁),则要返回true,否则返回false。

//独占锁
protected boolean tryAcquire(int arg) { throw new UnsupportedOperationException(); }
protected boolean tryRelease(int arg) { throw new UnsupportedOperationException(); }
//共享锁
protected int tryAcquireShared(int arg) { throw new UnsupportedOperationException(); }
protected boolean tryReleaseShared(int arg) { throw new UnsupportedOperationException(); }

下表为各个类对state值的判断

Class state 锁类型 说明
ReentrantLock 0 或 非0 独占锁 state可以理解为锁的唯一一把钥匙,若为0,说明钥匙没人用,当前线程获取钥匙开了锁,其他线程都等待;否则若exclusiveThread==currentThread,则重入;否则阻塞
CountDownLatch 是否大于0 共享锁 state可以理解为倒计时,若为0,说明倒计时结束,waiting()的线程可以执行(可能有多个线程同时竞争执行)
Semaphore 是否大于0 共享锁 此时state可以理解为通行证,若大于0,说明还有证书,当前线程可以执行;否则阻塞
ReentrantReadWriteLock.WriteLock 0 或 非0 独占锁 获取writeLock后,readLock无法再获取
ReentrantReadWriteLock.ReadLock 是否大于0 共享锁 获取reakLock后,writeLock无法再获取

你可能感兴趣的:(Java之AbstractQueuedSynchronizer(AQS))