AQS全称AbstractQueuedSychronizer,是java并发同步中重要抽象模板类,为其他同步类提供了框架基础。
其内部维护了一个有volatile修饰的int类型的变量state,用来表示同步状态。同时维护了一个队列完成资源排队等待。
AQS执行主要流程如下:
当一个线程进入同步块的时候,会调用acquire尝试获取资源,acquire会通过tryAcquire判断是否可以获取到资源,这个过程会使用到CAS。
如果可以获取到资源,则会直接执行。
如果获取不到资源,tryAquire会返回false,同时当前线程会被封装成一个Node节点,加入到等待队列尾部。同时线程会进行中断。
当一个线程释放同步状态时,会调用release方法,release会重置state状态,同时会唤醒队列中后续的节点,具体唤醒多少个节点会根据子类是独占锁还是共享锁。
TIP:具体如何唤醒会在后续章节描述
在ReentrantLock中,tryAquire方法
/**
* 非公平锁尝试获取锁
* @param acquires 操作数,在RenntrantLock中为1
* @return
*/
final boolean nonfairTryAcquire(int acquires) {
//当前线程
final Thread current = Thread.currentThread();
//获取AQS的state状态
int c = getState();
//当state为0,说明可以通过cas尝试获取锁
if (c == 0) {
//通过cas尝试获取锁
if (compareAndSetState(0, acquires)) {
//当cas成功,则将线当前线程设置为独占线程
setExclusiveOwnerThread(current);
return true;
}
}
//如果当前线程是独占线程,说明这里需要操作可重入
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}