Spec-Zone.ru › OpenJDK 21

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

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

toString

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

© 1993, 2023, 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/21/docs/api/java.base/java/util/concurrent/locks/ReentrantReadWriteLock.html

Spec-Zone.ru

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