这个方法前面已经完整分析过了,我们只关注一下ThreadB被唤醒以后的执行流程。
由于ThreadB的prev节点指向的是head,并且ThreadA已经释放了锁。所以这个时候调用tryAcquire方法时,可以顺利获取到锁
1. 把ThreadB节点当成head
2. 把原head节点的next节点指向为null
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);
}
}
图解分析
1. 设置新head节点的prev=null
2. 设置原head节点的next节点为null