AQS(AbstractQueuedSynchronizer)源码解析
理解
字面意思,抽象的同步器队列。
源码解析
AbstractOwnableSynchronizer
一个同步器可能只属于一个线程,设置同步器所属线程
AQS(AbstractQueuedSynchronizer)
提供了一个实现阻塞锁和同步器(信号,事件等)的框架,这个框架依赖于一个FIFO的队列
AQS的核心也包括了这些方面:同步队列,独占式锁的获取和释放,共享锁的获取和释放以及可中断锁,超时等待锁获取这些特性的实现
内部类:
Node
源码解析:
/** 指示节点正在共享模式下等待的标记 */
static final Node SHARED = new Node();
/** 指示节点正在以独占模式等待的标记 */
static final Node EXCLUSIVE = null;
/** 线程已经被取消 */
static final int CANCELLED = 1;
/** 后续的线程需要释放 */
static final int SIGNAL = -1;
/** 线程正在等待condition */
static final int CONDITION = -2;
/** 下一个acquireShared应该无条件传播 */
static final int PROPAGATE = -3;
/** CANCELLED, SIGNAL, CONDITION, PROPAGATE*/
volatile int waitStatus;
volatile Node prev;
volatile Node next;
volatile Thread thread;
/**
* Link to next node waiting on condition, or the special
* value SHARED.
*/
Node nextWaiter;
/**
* Returns true if node is waiting in shared mode.
*/
final boolean isShared() {
return nextWaiter == SHARED;
}
/**
* Returns previous node, or throws NullPointerException
*/
final Node predecessor() throws NullPointerException {
Node p = prev;
if (p == null)
throw new NullPointerException();
else
return p;
}
ConditionObject
数据存储为单链模式,主要用到Node.nextWaiter
private transient Node firstWaiter;
private transient Node lastWaiter;
节点生成
private Node addConditionWaiter() {
Node t = lastWaiter;
if (t != null && t.waitStatus != Node.CONDITION) {
unlinkCancelledWaiters(); //从队列中去掉waitStatus不是Node.CONDITION的节点
t = lastWaiter;
}
Node node = new Node(Thread.currentThread(), Node.CONDITION);
if (t == null)
firstWaiter = node; //添加节点
else
t.nextWaiter = node; //添加节点
lastWaiter = node;
return node;
}
其余方法
相关方法 | 原理 | 抛出异常 |
---|---|---|
awaitUninterruptibly | 1.addConditionWaiter 创建节点;2.判断是否加锁,3…死循环中LockSupport.park(this); | 否 |
await() | 原理大致同上 | 是,InterruptedException |
awaitNanos(long nanosTimeout) | 1.addConditionWaiter 创建节点;2.判断是否加锁,3…死循环中LockSupport.parkNanos(this, nanosTimeout); | 是,InterruptedException |
awaitUntil(Date deadline) | 1.addConditionWaiter 创建节点;2.判断是否加锁,3.死循环中LockSupport.parkNanos(this, nanosTimeout); | 是,InterruptedException |
await(long time, TimeUnit unit) | 1.addConditionWaiter 创建节点;2.判断是否加锁,3.死循环中LockSupport.parkNanos(this, nanosTimeout); | 是,InterruptedException |
signal() | 1.isHeldExclusively判断是否加锁;2.获取firstWaiter;3.移除头节点,4. 唤醒node中的线程LockSupport.unpark(node.thread) | 时,IllegalMonitorStateException |
signalAll() | 同上,不过3,4步骤是队列的节点循环 | 是,IllegalMonitorStateException |
synchronized锁+Object.wait机制 功能上和ReentrantLock+ConditionObject,原理可不一样
核心方法
属性
/**
* 等待队列的头,延迟初始化。除初始化外,只能通过setHead方法进行修改
* 注意:如果head存在,则保证其waitStatus不被取消.
*/
private transient volatile Node head;
/**
* 等待队列的尾部,延迟初始化。仅通过方法enq进行修改以添加新的等待节点
*/
private transient volatile Node tail;
/**
* 同步器状态
*/
private volatile int state;
独占锁方法
- 独占锁的获取(acquire方法)
1.acquire
以独占模式获取,忽略中断
//如果tryAcquire失败,会把线程加入等待队列
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
2.tryAcquire
试图以独占模式获取
未实现具体逻辑,具体的逻辑由子类负责,可以看看ReentrantLock.FairSync和ReentrantLock.NonfairSync
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
ReentrantLock.FairSync
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
//同步器未设置线程
if (c == 0) {
//如果等待队列没有等待线程,同时设置状态为1
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
//同步器设置线程
setExclusiveOwnerThread(current);
return true;
}
}
//如果线程重复加锁,则状态+1
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
ReentrantLock.NoFairSync原理和ReentrantLock.FairSync类似,只不过非公平锁不会判断等待队列是否为空,也就是执行hasQueuedPredecessors()判断。
3.addWaiter
向等待列表中添加结点(双向列表),返回新加结点
4.acquireQueued
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
//死循环
for (;;) {
//获取新结点的前面结点
final Node p = node.predecessor();
//如果前结点是头结点并且tryAcquire成功
if (p == head && tryAcquire(arg)) {
//设置新结点为头结点
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
5.shouldParkAfterFailedAcquire
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
int ws = pred.waitStatus;
if (ws == Node.SIGNAL)
return true;
//去掉链中CANCELLED的结点
if (ws > 0) {
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
pred.next = node;
} else {
//waitStatus=0或者PROPAGATE
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;
}
6.parkAndCheckInterrupt
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);
return Thread.interrupted();
}
流程图:
- 独占锁的释放(release方法)
1.release
public final boolean release(int arg) {
//同步器释放线程,重置状态
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
2.tryRelease
未实现具体逻辑,具体的逻辑由子类负责,可以看看ReentrantLock.Sync
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
2.unparkSuccessor
private void unparkSuccessor(Node node) {
int ws = node.waitStatus;
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);
//如果结点的下一个节点为空或者waitStatus为CANCELLED,则从尾部开始向前遍历结点,知道结点waitStatus不为CANCELLED,则唤醒该结点的线程;
//如果不满足上述条件,则唤醒下一个节点的线程
Node s = node.next;
if (s == null || s.waitStatus > 0) {
s = null;
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
s = t;
}
if (s != null)
LockSupport.unpark(s.thread);
}
- 可中断式获取锁(acquireInterruptibly方法)
和acquire原理一样,acquireInterruptibly会判断线程中断了吗,如果中断了,会抛出InterruptedException异常
- 超时等待式获取锁(tryAcquireNanos方法)
和acquire原理一样,acquireInterruptibly会判断线程中断了吗,如果中断了,会抛出InterruptedException异常;同时park换成了parkNanos加入了超时等待的设置
共享锁方法
- 共享锁的获取(acquireShared方法)
1.acquireShared
public final void acquireShared(int arg) {
//获取共享锁结果小于0,则doAcquireShared
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}
2.tryAcquireShared
未实现具体逻辑,具体的逻辑由子类负责,可以看看Semaphore.FairSync和Semaphore.NonfairSync
protected int tryAcquireShared(int arg) {
throw new UnsupportedOperationException();
}
Semaphore.FairSync
protected int tryAcquireShared(int acquires) {
//死循环,CAS原理,循环更新state,state-1
for (;;) {
//如果等待队列里面有结点,则获取失败
if (hasQueuedPredecessors())
return -1;
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
Semaphore.NonfairSync
和原理一样,只是没有hasQueuedPredecessors判断
3.doAcquireShared
private void doAcquireShared(int arg) {
//向等待队列中添加共享结点
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head) {
//尝试获取,r剩余个数
int r = tryAcquireShared(arg);
if (r >= 0) {
//传入新节点和剩余个数
setHeadAndPropagate(node, r);
p.next = null; // help GC
if (interrupted)
selfInterrupt();
failed = false;
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
4.setHeadAndPropagate
private void setHeadAndPropagate(Node node, int propagate) {
Node h = head; // Record old head for check below
setHead(node);
//唤醒共享锁的线程
if (propagate > 0 || h == null || h.waitStatus < 0 ||
(h = head) == null || h.waitStatus < 0) {
Node s = node.next;
if (s == null || s.isShared())
doReleaseShared();
}
}
5.doReleaseShared
共享模式的释放动作向后继发出信号并确保
传播
private void doReleaseShared() {
for (;;) {
Node h = head;
if (h != null && h != tail) {
int ws = h.waitStatus;
if (ws == Node.SIGNAL) {
if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
continue; // loop to recheck cases
unparkSuccessor(h);
}
else if (ws == 0 &&
!compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
continue; // loop on failed CAS
}
if (h == head) // loop if head changed
break;
}
}
- 共享锁的释放(releaseShared方法)
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
- 可中断式获取锁(acquireSharedInterruptibly方法)
和独占锁acquireInterruptibly类似 - 超时等待式获取锁(tryAcquireSharedNanos方法)
和独占锁tryAcquireNanos类似