首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在AQS(AbstractQueuedSynchronizer)的await方法中使用"while“

为什么在AQS(AbstractQueuedSynchronizer)的await方法中使用"while“
EN

Stack Overflow用户
提问于 2020-08-24 23:09:09
回答 3查看 101关注 0票数 3

在AQS的await方法(AbstractQueuedSynchronizer)中:我想知道whilewhile (!isOnSyncQueue(node)) {中的含义

我认为如果这个节点被正常唤醒(没有被中断),它肯定会在信号方法被另一个线程执行后被移到同步队列中,然后在另一个线程中执行解锁方法来唤醒。

因此,可能存在节点正常唤醒,但不在同步队列中的情况?如果这不可能,我认为这里应该使用if而不是while

代码语言:javascript
复制
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);
}
EN

回答 3

Stack Overflow用户

发布于 2020-08-24 23:15:17

唤醒有两种口味。通常的类型和spurious类型。这段代码:

代码语言:javascript
复制
while (!isOnSyncQueue(node)) {
    ...
}

保持循环,直到isOnSyncQueue(node)返回false并且是while而不是if,因为唤醒可能是虚假的,而不是因为正在等待的条件已经发生。

票数 3
EN

Stack Overflow用户

发布于 2020-08-24 23:18:55

代码语言:javascript
复制
while (!isOnSyncQueue(node)) {
    LockSupport.park(this);
    if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
        break;
}

这样做的目的是执行大括号{}中的命令,直到isOnSyncQueue(node)返回false。如果它是一个if而不是while,那么这些语句将只执行一次。

票数 1
EN

Stack Overflow用户

发布于 2021-08-19 12:28:51

避免由用户停车,而不是通过信号,以增强鲁棒性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63563728

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档