AQS.acquireQueued
作者:互联网
通过addWaiter方法把线程添加到链表后,会接着把Node作为参数传递给acquireQueued方法,去竞争锁
1. 获取当前节点的prev节点
2. 如果prev节点为head节点,那么它就有资格去争抢锁,调用tryAcquire抢占锁
3. 抢占锁成功以后,把获得锁的节点设置为head,并且移除原来的初始化head节点
4. 如果获得锁失败,则根据waitStatus决定是否需要挂起线程
5. 最后,通过cancelAcquire取消获得锁的操作
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();//获
取当前节点的prev节点
if (p == head && tryAcquire(arg)) {//如
果是head节点,说明有资格去争抢锁
setHead(node);
//获取锁成功,也就是
ThreadA已经释放了锁,然后设置head为ThreadB获得执行权
限
p.next = null; //把原head节点从链表中
移除
failed = false;
return interrupted;
}
//ThreadA可能还没释放锁,使得ThreadB在执
行tryAcquire时会返回false
if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt())
interrupted = true; //并且返回当前线程
在等待过程中有没有中断过。
}
} finally {
if (failed)
cancelAcquire(node);
}
}
标签:node,head,false,AQS,tryAcquire,acquireQueued,boolean,节点 来源: https://blog.csdn.net/Leon_Jinhai_Sun/article/details/111768131