Зачем использовать «while» в методе await AQS (AbstractQueuedSynchronizer)

#java #java.util.concurrent

#java #java.util.concurrent

Вопрос:

В методе await AQS (AbstractQueuedSynchronizer): Я хочу знать значение while в while (!isOnSyncQueue(node)) {

Я думаю, что если этот узел будет разбужен нормально (без прерывания), он обязательно будет перемещен в очередь синхронизации после того, как метод signal будет выполнен другим потоком, а затем разбужен путем выполнения метода 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) amp;amp; interruptMode != THROW_IE)
        interruptMode = REINTERRUPT;
    if (node.nextWaiter != null) // clean up if cancelled
        unlinkCancelledWaiters();
    if (interruptMode != 0)
        reportInterruptAfterWait(interruptMode);
}

  

Ответ №1:

Пробуждения бывают двух видов. Обычный вид и ложный вид. Этот код:

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

Продолжает цикл до isOnSyncQueue(node) возврата false и является a while вместо if an, потому что пробуждение может быть ложным, а не потому, что произошло ожидаемое условие.

Ответ №2:

 while (!isOnSyncQueue(node)) {
    LockSupport.park(this);
    if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
        break;
}
  

Что это делает, так это выполняет команды внутри пары фигурных скобок {}, пока isOnSyncQueue(node) не вернет false . Если бы это было if вместо a while , эти инструкции были бы выполнены только один раз.

Комментарии:

1. Извините, возможно, я не совсем ясно спрашиваю. На самом деле, я хочу спросить, почему автор написал это таким образом (while вместо if), теперь я знаю, потому что ложное пробуждение … но и вам спасибо

Ответ №3:

Избегайте разблокировки пользователем, но не сигналом для надежности.