Spec-Zone.ru › OpenJDK 27

Класс ReentrantReadWriteLock

java.lang.Object
java.util.concurrent.locks.ReentrantReadWriteLock
Все реализуемые интерфейсы:
Serializable, ReadWriteLock
public class ReentrantReadWriteLock extends Object implements ReadWriteLock, Serializable
Реализация ReadWriteLock, поддерживающая семантику, аналогичную ReentrantLock.

Этот класс обладает следующими свойствами:

  • Порядок получения

    Этот класс не устанавливает предпочтительный порядок доступа к блокировке для читателей или писателей. Однако он поддерживает необязательную политику справедливости.

    Несправедливый режим (по умолчанию)
    При создании в несправедливом режиме (по умолчанию) порядок получения блокировок чтения и записи не определен и зависит от ограничений реентерабельности. Несправедливая блокировка, за которую непрерывно конкурируют потоки, может неопределенно долго откладывать выполнение одного или нескольких потоков-читателей или потоков-писателей, но обычно обеспечивает более высокую пропускную способность, чем справедливая блокировка.
    Справедливый режим
    При создании в справедливом режиме потоки конкурируют за получение блокировки в приблизительном порядке поступления. Когда текущая блокировка освобождается, блокировка записи назначается либо потоку-писателю, который дольше всех ожидает, либо группе потоков-читателей, если она ожидает дольше всех потоков-писателей.

    Поток, пытающийся получить справедливую блокировку чтения (не реентерабельно), будет заблокирован, если удерживается блокировка записи или ожидает поток-писатель. Поток не получит блокировку чтения, пока самый давно ожидающий поток-писатель не получит и не освободит блокировку записи. Разумеется, если ожидающий писатель прекратит ожидание и в очереди останутся один или несколько потоков-читателей, ожидающих дольше остальных, а блокировка записи будет свободна, этим читателям будет назначена блокировка чтения.

    Поток, пытающийся получить справедливую блокировку записи (не реентерабельно), будет заблокирован, пока обе блокировки — чтения и записи — не освободятся (это означает, что ожидающих потоков нет). (Обратите внимание: неблокирующие методы ReentrantReadWriteLock.ReadLock.tryLock() и ReentrantReadWriteLock.WriteLock.tryLock() не учитывают эту настройку справедливости и немедленно получают блокировку, если это возможно, независимо от ожидающих потоков.)

  • Реентерабельность

    Эта блокировка позволяет как читателям, так и писателям повторно получать блокировки чтения или записи по принципу ReentrantLock. Потоки-читатели, не являющиеся реентерабельными, не допускаются, пока пишущий поток не освободит все удерживаемые им блокировки записи.

    Кроме того, писатель может получить блокировку чтения, но не наоборот. Среди прочего, реентерабельность может быть полезна, когда блокировки записи удерживаются во время вызовов или обратных вызовов методов, выполняющих чтение под блокировками чтения. Если читатель попытается получить блокировку записи, ему это никогда не удастся.

    Примечание. Если вы не полагаетесь на реентерабельность, StampedLock может обеспечить более высокую производительность, например: ReadWriteLock lock = new StampedLock().asReadWriteLock().

  • Понижение блокировки

    Реентерабельность также позволяет понизить блокировку записи до блокировки чтения: для этого нужно получить блокировку записи, затем блокировку чтения и после этого освободить блокировку записи. Однако повысить блокировку чтения до блокировки записи невозможно.

  • Прерывание при получении блокировки

    Блокировки чтения и записи поддерживают прерывание во время получения блокировки.

  • Поддержка Condition

    Блокировка записи предоставляет реализацию Condition, которая ведет себя в отношении блокировки записи так же, как реализация Condition, предоставляемая ReentrantLock.newCondition() для ReentrantLock. Разумеется, эту Condition можно использовать только с блокировкой записи.

    Блокировка чтения не поддерживает Condition, а readLock().newCondition() вызывает UnsupportedOperationException.

  • Инструментирование

    Этот класс поддерживает методы для определения того, удерживаются ли блокировки или конкурируют ли за них потоки. Эти методы предназначены для мониторинга состояния системы, а не для управления синхронизацией.

Сериализация этого класса ведет себя так же, как у встроенных блокировок: десериализованная блокировка находится в разблокированном состоянии независимо от ее состояния на момент сериализации.

Примеры использования. Ниже приведен фрагмент кода, показывающий, как понизить блокировку после обновления кэша (обработка исключений особенно сложна при работе с несколькими блокировками без вложенной структуры):

class CachedData {
  Object data;
  boolean cacheValid;
  final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

  void processCachedData() {
    rwl.readLock().lock();
    // Code between the lock() above, and the unlock() below must not throw
    if (!cacheValid) {
      // Must release read lock before acquiring write lock
      rwl.readLock().unlock();
      rwl.writeLock().lock();
      try {
        // Recheck state because another thread might have
        // acquired write lock and changed state before we did.
        if (!cacheValid) {
          data = ...;
          cacheValid = true;
        }
        // Downgrade by acquiring read lock before releasing write lock
        rwl.readLock().lock();
      } finally {
        rwl.writeLock().unlock(); // Unlock write, still hold read
      }
    }
    // Make sure that code that could throw is executed inside the try block
    try {
      use(data);
    } finally {
      rwl.readLock().unlock();
    }
  }
}
ReentrantReadWriteLock можно использовать для повышения параллелизма в некоторых случаях работы с некоторыми видами коллекций. Обычно это имеет смысл только тогда, когда коллекции предположительно велики, к ним обращается больше потоков-читателей, чем потоков-писателей, а выполняемые операции достаточно затратны, чтобы накладные расходы на синхронизацию были оправданы. Например, ниже приведен класс, использующий TreeMap, которая предположительно велика и доступна из нескольких потоков.
class RWDictionary {
  private final Map<String, Data> m = new TreeMap<>();
  private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
  private final Lock r = rwl.readLock();
  private final Lock w = rwl.writeLock();

  public Data get(String key) {
    r.lock();
    try { return m.get(key); }
    finally { r.unlock(); }
  }
  public List<String> allKeys() {
    r.lock();
    try { return new ArrayList<>(m.keySet()); }
    finally { r.unlock(); }
  }
  public Data put(String key, Data value) {
    w.lock();
    try { return m.put(key, value); }
    finally { w.unlock(); }
  }
  public void clear() {
    w.lock();
    try { m.clear(); }
    finally { w.unlock(); }
  }
}

Примечания по реализации

Эта блокировка поддерживает не более Integer.MAX_VALUE рекурсивных блокировок записи и Integer.MAX_VALUE блокировок чтения. Попытки превысить эти пределы приводят к тому, что методы блокировки выбрасывают Error.

Начиная с:
1.5
См. также:
  • Форма сериализации

Краткое описание вложенных классов

Модификатор и тип Класс Описание
static class  ReentrantReadWriteLock.ReadLock
Блокировка, возвращаемая методом readLock().
static class  ReentrantReadWriteLock.WriteLock
Блокировка, возвращаемая методом writeLock().

Краткое описание конструкторов

Конструктор Описание
ReentrantReadWriteLock()
Создает новый ReentrantReadWriteLock со свойствами порядка по умолчанию (несправедливый режим).
ReentrantReadWriteLock(boolean fair)
Создает новый ReentrantReadWriteLock с указанной политикой справедливости.

Краткое описание методов

Модификатор и тип Метод Описание
protected Thread getOwner()
Возвращает поток, который в данный момент владеет блокировкой записи, или null, если такой поток отсутствует.
protected Collection<Thread> getQueuedReaderThreads()
Возвращает коллекцию, содержащую потоки, которые могут ожидать получения блокировки чтения.
protected Collection<Thread> getQueuedThreads()
Возвращает коллекцию, содержащую потоки, которые могут ожидать получения блокировки чтения или записи.
protected Collection<Thread> getQueuedWriterThreads()
Возвращает коллекцию, содержащую потоки, которые могут ожидать получения блокировки записи.
final int getQueueLength()
Возвращает оценочное количество потоков, ожидающих получения блокировки чтения или записи.
int getReadHoldCount()
Возвращает количество реентерабельных блокировок чтения, удерживаемых текущим потоком.
int getReadLockCount()
Возвращает количество блокировок чтения, удерживаемых для этой блокировки.
protected Collection<Thread> getWaitingThreads(Condition condition)
Возвращает коллекцию, содержащую потоки, которые могут ожидать выполнения указанного условия, связанного с блокировкой записи.
int getWaitQueueLength(Condition condition)
Возвращает оценочное количество потоков, ожидающих выполнения указанного условия, связанного с блокировкой записи.
int getWriteHoldCount()
Возвращает количество реентерабельных блокировок записи, удерживаемых текущим потоком.
final boolean hasQueuedThread(Thread thread)
Проверяет, ожидает ли указанный поток получения блокировки чтения или записи.
final boolean hasQueuedThreads()
Проверяет, ожидают ли какие-либо потоки получения блокировки чтения или записи.
boolean hasWaiters(Condition condition)
Проверяет, ожидают ли какие-либо потоки выполнения указанного условия, связанного с блокировкой записи.
final boolean isFair()
Возвращает true, если для этой блокировки включен справедливый режим.
boolean isWriteLocked()
Проверяет, удерживается ли блокировка записи каким-либо потоком.
boolean isWriteLockedByCurrentThread()
Проверяет, удерживается ли блокировка записи текущим потоком.
ReentrantReadWriteLock.ReadLock readLock()
Возвращает блокировку, используемую для чтения.
String toString()
Возвращает строку, идентифицирующую эту блокировку и описывающую ее состояние.
ReentrantReadWriteLock.WriteLock writeLock()
Возвращает блокировку, используемую для записи.

Методы, объявленные в классе Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
Модификатор и тип Метод Описание
protected Object clone()
Создает и возвращает копию этого объекта.
boolean equals(Object obj)
Показывает, равен ли этот объект другому объекту.
protected void finalize()
Устарело, будет удалено: этот элемент API может быть удален в будущей версии.
Финализация объявлена устаревшей и будет удалена в одном из следующих выпусков.
final Class<?> getClass()
Возвращает класс времени выполнения этого Object.
int hashCode()
Возвращает хеш-код этого объекта.
final void notify()
Пробуждает один поток, ожидающий на мониторе этого объекта.
final void notifyAll()
Пробуждает все потоки, ожидающие на мониторе этого объекта.
final void wait()
Заставляет текущий поток ожидать пробуждения, обычно в результате уведомления или прерывания.
final void wait(long timeoutMillis)
Заставляет текущий поток ожидать пробуждения, обычно в результате уведомления или прерывания, либо до истечения заданного промежутка реального времени.
final void wait(long timeoutMillis, int nanos)
Заставляет текущий поток ожидать пробуждения, обычно в результате уведомления или прерывания, либо до истечения заданного промежутка реального времени.

Подробное описание конструкторов

ReentrantReadWriteLock

public ReentrantReadWriteLock()
Создает новый ReentrantReadWriteLock со свойствами порядка по умолчанию (несправедливый режим).

ReentrantReadWriteLock

public ReentrantReadWriteLock(boolean fair)
Создает новый ReentrantReadWriteLock с указанной политикой справедливости.
Параметры:
fair — true, если для этой блокировки следует использовать справедливую политику упорядочения

Подробное описание методов

writeLock

public ReentrantReadWriteLock.WriteLock writeLock()
Описание скопировано из интерфейса: ReadWriteLock
Возвращает блокировку, используемую для записи.
Определено в:
writeLock в интерфейсе ReadWriteLock
Возвращает:
блокировку, используемую для записи

readLock

public ReentrantReadWriteLock.ReadLock readLock()
Описание скопировано из интерфейса: ReadWriteLock
Возвращает блокировку, используемую для чтения.
Определено в:
readLock в интерфейсе ReadWriteLock
Возвращает:
блокировку, используемую для чтения

isFair

public final boolean isFair()
Возвращает true, если для этой блокировки включен справедливый режим.
Возвращает:
true, если для этой блокировки включен справедливый режим

getOwner

protected Thread getOwner()
Возвращает поток, который в данный момент владеет блокировкой записи, или null, если такой поток отсутствует. Если этот метод вызывается потоком, который не является владельцем блокировки, возвращаемое значение отражает наилучшую возможную оценку текущего состояния блокировки. Например, владелец может на короткое время оказаться null, даже если потоки пытаются получить блокировку, но еще не получили ее. Этот метод предназначен для упрощения создания подклассов, предоставляющих более широкие возможности мониторинга блокировок.
Возвращает:
владельца или null, если такой поток отсутствует

getReadLockCount

public int getReadLockCount()
Возвращает количество блокировок чтения, удерживаемых для этой блокировки. Этот метод предназначен для мониторинга состояния системы, а не для управления синхронизацией.
Возвращает:
количество удерживаемых блокировок чтения

isWriteLocked

public boolean isWriteLocked()
Проверяет, удерживается ли блокировка записи каким-либо потоком. Этот метод предназначен для мониторинга состояния системы, а не для управления синхронизацией.
Возвращает:
true, если блокировку записи удерживает какой-либо поток, и false в противном случае

isWriteLockedByCurrentThread

public boolean isWriteLockedByCurrentThread()
Проверяет, удерживается ли блокировка записи текущим потоком.
Возвращает:
true, если текущий поток удерживает блокировку записи, и false в противном случае

getWriteHoldCount

public int getWriteHoldCount()
Возвращает количество реентерабельных блокировок записи, удерживаемых текущим потоком. Поток-писатель удерживает блокировку для каждого вызова блокировки, которому не соответствует вызов разблокировки.
Возвращает:
количество удержаний блокировки записи текущим потоком или ноль, если текущий поток не удерживает блокировку записи

getReadHoldCount

public int getReadHoldCount()
Возвращает количество реентерабельных блокировок чтения, удерживаемых текущим потоком. Поток-читатель удерживает блокировку для каждого вызова блокировки, которому не соответствует вызов разблокировки.
Возвращает:
количество удержаний блокировки чтения текущим потоком или ноль, если текущий поток не удерживает блокировку чтения
Начиная с:
1.6

getQueuedWriterThreads

protected Collection<Thread> getQueuedWriterThreads()
Возвращает коллекцию, содержащую потоки, которые могут ожидать получения блокировки записи. Поскольку фактический набор потоков может динамически изменяться во время формирования результата, возвращаемая коллекция представляет собой лишь наилучшую возможную оценку. Элементы возвращаемой коллекции не упорядочены. Этот метод предназначен для упрощения создания подклассов, предоставляющих более широкие возможности мониторинга блокировок.
Возвращает:
коллекцию потоков

getQueuedReaderThreads

protected Collection<Thread> getQueuedReaderThreads()
Возвращает коллекцию, содержащую потоки, которые могут ожидать получения блокировки чтения. Поскольку фактический набор потоков может динамически изменяться во время формирования результата, возвращаемая коллекция представляет собой лишь наилучшую возможную оценку. Элементы возвращаемой коллекции не упорядочены. Этот метод предназначен для упрощения создания подклассов, предоставляющих более широкие возможности мониторинга блокировок.
Возвращает:
коллекцию потоков

hasQueuedThreads

public final boolean hasQueuedThreads()
Проверяет, ожидают ли какие-либо потоки получения блокировки чтения или записи. Обратите внимание: поскольку отмена ожидания может произойти в любой момент, результат true не гарантирует, что какой-либо другой поток когда-либо получит блокировку. Этот метод предназначен главным образом для мониторинга состояния системы.
Возвращает:
true, если другие потоки могут ожидать получения блокировки

hasQueuedThread

public final boolean hasQueuedThread(Thread thread)
Проверяет, ожидает ли указанный поток получения блокировки чтения или записи. Обратите внимание: поскольку отмена ожидания может произойти в любой момент, результат true не гарантирует, что этот поток когда-либо получит блокировку. Этот метод предназначен главным образом для мониторинга состояния системы.
Параметры:
thread — поток
Возвращает:
true, если указанный поток стоит в очереди и ожидает эту блокировку
Выбрасывает:
NullPointerException — если поток равен null

getQueueLength

public final int getQueueLength()
Возвращает оценочное количество потоков, ожидающих получения блокировки чтения или записи. Это значение является лишь оценкой, поскольку количество потоков может динамически изменяться во время обхода внутренних структур данных этим методом. Метод предназначен для мониторинга состояния системы, а не для управления синхронизацией.
Возвращает:
оценочное количество потоков, ожидающих эту блокировку

getQueuedThreads

protected Collection<Thread> getQueuedThreads()
Возвращает коллекцию, содержащую потоки, которые могут ожидать получения блокировки чтения или записи. Поскольку фактический набор потоков может динамически изменяться во время формирования результата, возвращаемая коллекция представляет собой лишь наилучшую возможную оценку. Элементы возвращаемой коллекции не упорядочены. Этот метод предназначен для упрощения создания подклассов, предоставляющих более широкие возможности мониторинга.
Возвращает:
коллекцию потоков

hasWaiters

public boolean hasWaiters(Condition condition)
Проверяет, ожидают ли какие-либо потоки выполнения указанного условия, связанного с блокировкой записи. Обратите внимание: поскольку тайм-ауты и прерывания могут произойти в любой момент, результат true не гарантирует, что последующий вызов signal разбудит какие-либо потоки. Этот метод предназначен главным образом для мониторинга состояния системы.
Параметры:
condition — условие
Возвращает:
true, если есть ожидающие потоки
Выбрасывает:
IllegalMonitorStateException — если эта блокировка не удерживается
IllegalArgumentException — если указанное условие не связано с этой блокировкой
NullPointerException — если условие равно null

getWaitQueueLength

public int getWaitQueueLength(Condition condition)
Возвращает оценочное количество потоков, ожидающих указанного условия, связанного с блокировкой записи. Обратите внимание: поскольку тайм-ауты и прерывания могут произойти в любой момент, эта оценка служит только верхней границей фактического количества ожидающих потоков. Метод предназначен для мониторинга состояния системы, а не для управления синхронизацией.
Параметры:
condition — условие
Возвращает:
оценочное количество ожидающих потоков
Выбрасывает:
IllegalMonitorStateException — если эта блокировка не удерживается
IllegalArgumentException — если указанное условие не связано с этой блокировкой
NullPointerException — если условие равно null

getWaitingThreads

protected Collection<Thread> getWaitingThreads(Condition condition)
Возвращает коллекцию, содержащую потоки, которые могут ожидать указанного условия, связанного с блокировкой записи. Поскольку фактический набор потоков может динамически изменяться во время формирования результата, возвращаемая коллекция представляет собой лишь наилучшую возможную оценку. Элементы возвращаемой коллекции не упорядочены. Этот метод предназначен для упрощения создания подклассов, предоставляющих более широкие возможности мониторинга условий.
Параметры:
condition — условие
Возвращает:
коллекцию потоков
Выбрасывает:
IllegalMonitorStateException — если эта блокировка не удерживается
IllegalArgumentException — если указанное условие не связано с этой блокировкой
NullPointerException — если условие равно null

toString

public String toString()
Возвращает строку, идентифицирующую эту блокировку и описывающую ее состояние. Состояние в квадратных скобках включает строку "Write locks =", за которой следует количество реентерабельно удерживаемых блокировок записи, и строку "Read locks =", за которой следует количество удерживаемых блокировок чтения.
Переопределяет:
toString в классе Object
Возвращает:
строку, идентифицирующую эту блокировку и описывающую ее состояние

Сообщить об ошибке или предложить улучшение
Дополнительную справочную информацию по API и документацию для разработчиков см. в разделе документации Java SE, содержащем более подробные описания для разработчиков, концептуальные обзоры, определения терминов, обходные решения и рабочие примеры кода. Другие версии.
Java является товарным знаком или зарегистрированным товарным знаком Oracle и/или ее аффилированных лиц в США и других странах.
Авторское право © 1993, 2026, Oracle и/или ее аффилированные лица, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
Все права защищены. Использование регулируется условиями лицензии и политикой распространения документации.

© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API