当我阅读acquireQueued
方法的代码时,我正在研究AbstractQueuedSynchronizer类的源代码:
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);
}
}
语句final Node p = node.predecessor();
表示获取当前节点的上一个节点p
。下一条if语句尝试比较p
节点和head
节点。
我的疑问是如何更改head
节点,以便代码可以输入if语句,以及发生更改的代码块
在shouldParkAfterFailedAcquire
/ parkAndCheckInterrupt
/ release
/ unparkSuccessor
方法中似乎找不到代码块
答案 0 :(得分:0)
很明显,当第二个节点被唤醒并tryAcquire成功时,它成为头节点。
setHead(node);
然后,当第三个节点唤醒时,头节点发生更改。
输入if语句不一定意味着磁头已更改。
如果该节点的前一个节点被取消,则该节点可以充当头节点的后节点。在shouldParkAfterFailedAcquire
方法中查看详细信息