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

标签 java java.util.concurrent

await AQS的方法(AbstractQueuedSynchronizer): 我想知道 while (!isOnSyncQueue(node)) {

while 的含义

我觉得如果这个节点正常被唤醒(没有被中断),肯定会在另一个线程执行完signal方法后移到sync队列,然后在另一个线程执行unlock方法唤醒.

所以可能会出现节点正常唤醒,但不在同步队列中的情况?如果那不可能,我认为应该在这里使用 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);
}

最佳答案

唤醒有两种形式。通常的种类和spurious种类。这段代码:

while (!isOnSyncQueue(node)) {
    ...
}

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

关于java - 为什么在AQS(AbstractQueuedSynchronizer)的await方法中使用 "while",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63563728/

相关文章:

java - AtomicInteger 与 Java 中的同步 int 变量 : performance difference

multithreading - LongAdder Striped64 wasUncontended 实现细节

java - 云端点更新方法在 mgr.close() 处崩溃

java - 我可以为接口(interface)创建一个对象吗?

java - 如何从 Java 中的 html 代码中删除/替换以下内联 css 样式

Java 7 : How to execute parallel tasks in batches?

java - for循环与并发修改异常中增强for循环的比较

java - 如何准确测量 drawTextOnPath() 在 Canvas 上绘制的文本的像素大小

java - 增量数学问题

具有资源锁定的java模型客户端服务器架构