Spec-Zone.ru › OpenJDK 25

Класс 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. Нереентерабельные потоки-читатели не допускаются, пока пишущий поток не освободит все удерживаемые им блокировки записи.

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

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

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

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

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

  • Поддержка 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

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

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, 2025, 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.
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/concurrent/locks/ReentrantReadWriteLock.html

Spec-Zone.ru

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