什么是AQS
抽象了一套多线程访问共享资源的同步器框架,依赖一个状态值(state)。
有以下几个重要的方法变量:
1、state :是一个volatile修饰的状态值,当为0的时候,标识同步器没有被线程占用,为1的时候,被某一线程占用。
2、ExclueOwnerThread:用来记录当前同步器被哪个线程占用。
3、ELH队列:是一个Node节点的双向队列,用来存储没有获取到锁,进行锁等待的线程
三大特征
自旋、CAS、LocksSupport
获取锁
以ReentrantLock为例
ReentrantLock 中有一个抽象内部类Sync, Sync继承了AbstractQueuedSynchronizer,并且定义了像lock()、tryRelease()等方法;并且在ReentrantLock内部还定义了有NonfairSync类和FairSync类。
ReentrantLock lock = new ReentrantLock(true);
调用lock.lock()来尝试获取锁,底层调用AQS的acquire方法
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}
1、判断状态为是否为0
1.1 为0,判断是否公平锁
1.1.1 如果是公平锁,判断等锁队列是否为空;
1.1.1.1 等待队列为空,则状态位设为1(使用CAS原理),这样其他线程就无法获取到锁,同时将锁的ExclueOwnerThread 标 为当前线程
1.1.1.2 等待队列不为空,则加入到CLH队列的后面
1.1.2 如果为非公平锁,则状态位设为1,这样其他线程就无法获取到锁,同时将锁的ExclueOwnerThread 标 为当前线程
1.2 状态位不为0
1.2.1 查看ExclueOwnerThread = Current Thread ??
1.2.1.1 若是,则状态位+1
1.2.1.2 若不是,则获取锁失败,加入CLH队列
后续待更新