在AQS的await方法(AbstractQueuedSynchronizer)中:我想知道while在while (!isOnSyncQueue(node)) {中的含义
我认为如果这个节点被正常唤醒(没有被中断),它肯定会在信号方法被另一个线程执行后被移到同步队列中,然后在另一个线程中执行解锁方法来唤醒。
因此,可能存在节点正常唤醒,但不在同步队列中的情况?如果这不可能,我认为这里应该使用if而不是while
public final void await() throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter();
int savedState = fullyRelease(node);
int interruptMode = 0;
while (!isOnSyncQueue(node)) {
LockSupport.park(this);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT;
if (node.nextWaiter != null) // clean up if cancelled
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
}发布于 2020-08-24 23:15:17
唤醒有两种口味。通常的类型和spurious类型。这段代码:
while (!isOnSyncQueue(node)) {
...
}保持循环,直到isOnSyncQueue(node)返回false并且是while而不是if,因为唤醒可能是虚假的,而不是因为正在等待的条件已经发生。
发布于 2020-08-24 23:18:55
while (!isOnSyncQueue(node)) {
LockSupport.park(this);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}这样做的目的是执行大括号{}中的命令,直到isOnSyncQueue(node)返回false。如果它是一个if而不是while,那么这些语句将只执行一次。
发布于 2021-08-19 12:28:51
避免由用户停车,而不是通过信号,以增强鲁棒性。
https://stackoverflow.com/questions/63563728
复制相似问题