Spec-Zone.ru › OpenJDK 24

Класс 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(); }
   }
 }

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

Эта блокировка поддерживает максимальное количество 65535 рекурсивных блокировок записи и 65535 блокировок чтения. Попытки превысить эти пределы приводят к исключению 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()
Возвращает блокировку, используемую для записи.

Методы, объявленные в классе java.lang.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.
Возвращает:
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)
Возвращает коллекцию, содержащую те потоки, которые могут ожидать на заданном условии, связанном с блокировкой записи. Поскольку фактический набор потоков может динамически изменяться во время построения этого результата, возвращаемая коллекция является лишь приблизительной оценкой. Элементы возвращаемой коллекции не упорядочены. Этот метод предназначен для облегчения построения подклассов, предоставляющих более расширенные средства мониторинга условий.
Parameters:
condition - условие
Returns:
коллекция потоков
Throws:
IllegalMonitorStateException - если эта блокировка не удерживается
IllegalArgumentException - если заданное условие не связано с этой блокировкой
NullPointerException - если условие равно null

toString

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

© 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://download.java.net/java/early_access/jdk24/docs/api/java.base/java/util/concurrent/locks/ReentrantReadWriteLock.html

Spec-Zone.ru

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