aqs是一个很重要的并发框架,熟悉之后可以很方便的构造自己的并发工具。
aqs核心在于一个acquire方法。
public final void acquire(int arg) {
if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)){
selfInterrupt();
}
}
1.tryAcquire(arg)
获取锁,获取成功直接结束,
获取失败,进入2。
2.addWaiter(Node.EXCLUSIVE)
获取失败表示有人占据了锁,进入等待队列,处理完成进入3。
3.acquireQueued(node,arg)
返回true会中断,大部分情况会返回false。
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
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);
}
}
finally逻辑先无视。
1.p == head
判断成功走2,不成功走3。
2.tryAcquire(arg)
获取成功返回,失败走3。
3.shouldParkAfterFailedAcquire(p, node)
成功走4,不成功回到1。
4.parkAndCheckInterrupt()
成功修改状态,失败不修改,然后回到1。