英文:
Why use "while" in the await method of AQS(AbstractQueuedSynchronizer)
问题
在AQS(AbstractQueuedSynchronizer)的await方法中:
我想知道在以下代码中的while
的含义是什么:
while (!isOnSyncQueue(node)) {
我认为如果这个节点正常被唤醒(没有被中断),那么在另一个线程执行了signal
方法之后,它肯定会被移动到同步队列,并且会在另一个线程执行解锁方法时被唤醒。
所以是否可能出现节点正常唤醒但不在同步队列中的情况呢?如果不可能的话,我认为这里应该使用if
而不是while
。
(请注意,这是对代码中while
语句的解释和提问,并非翻译。)
英文:
In the await method of AQS (AbstractQueuedSynchronizer):
I want to know the meaning of while
in while (!isOnSyncQueue(node)) {
I think that if this node is woken up normally (without being interrupted), It will definitely be moved to the sync queue after the signal method is executed by another thread, and then woken up by executing the unlock method in another thread.
So there could be a situation where a node is waking up normally, but not in the sync queue? If that's not possible, I think if
should be used here instead of 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);
}
答案1
得分: 3
唤醒有两种类型。一种是常规类型,另一种是虚假的类型。此代码:
while (!isOnSyncQueue(node)) {
...
}
会不断循环,直到isOnSyncQueue(node)
返回false
,并且使用的是while
而不是if
,因为唤醒可能是虚假的,而不是因为等待的条件已发生。
英文:
Wakeups come in two flavours. The usual kind and the spurious kind. This code:
while (!isOnSyncQueue(node)) {
...
}
Keeps looping until isOnSyncQueue(node)
returns false
and is a while
instead of an if
, because the wake up might be spurious and not because the condition being waited for has occurred.
答案2
得分: 1
当 (!isOnSyncQueue(node)) {
LockSupport.park(this);
若 ( (interruptMode = checkInterruptWhileWaiting(node)) != 0 )
中断;
}
这段代码的作用是在花括号 {} 中的命令,会在 isOnSyncQueue(node)
返回 false 之前不断执行。如果用 if
而不是 while
,这些语句只会被执行一次。
英文:
while (!isOnSyncQueue(node)) {
LockSupport.park(this);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}
What this does is execute the commands inside the pair of curly braces {}, until isOnSyncQueue(node)
returns false. If it was an if
instead of a while
those statements would be executed only once.
答案3
得分: 0
避免由用户取消停放,但不通过信号进行,以提高鲁棒性。
英文:
Avoid unparking by the user but not by signal for robustness.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论