Получает ли LinkedBlockQueue блокировку при вызове await?

#java #concurrency

#java #параллелизм

Вопрос:

Я нашел следующий исходный код в LinkedBlockingQueue

 public E take() throws InterruptedException {
        E x;
        int c = -1;
        final AtomicInteger count = this.count;
        final ReentrantLock takeLock = this.takeLock;
        takeLock.lockInterruptibly();
        try {
            while (count.get() == 0) {
                notEmpty.await();
            }
            x = dequeue();
            c = count.getAndDecrement();
            if (c > 1)
                notEmpty.signal();
        } finally {
            takeLock.unlock();
        }
        if (c == capacity)
            signalNotFull();
        return x;
    }
  

await Метод снимает блокировку, и после того, как он сигнализируется, в цикле while снова кажется, что у него нет блокировки. И в notEmpty<Condition> нем указывается, что IllegalMonitorStateException будет выброшено, если не удерживать блокировку во время вызова await .

Это меня смутило .. Удерживает ли он блокировку или нет в конечном итоге?

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

1. Он удерживает блокировку, как только await() возвращается. Стандартное поведение, аналогичное Object.wait() . Прочитайте документацию вместо того, чтобы говорить «кажется». Это многолетний код JDK, и вы утверждаете, что он в корне нарушен. docs.oracle.com/javase/tutorial/essential/concurrency /…

Ответ №1:

конечно, он содержит lock.to судите, могут ли данные быть токеном из очереди, он использует цикл. когда очередь все еще пуста, она должна снова ожидать, пока ее s notified and the queue количество не станет равным нулю.