Spec-Zone.ru › OpenJDK 17

Класс 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();
     }
   }
 }
Блокировки ReentrantReadWrite могут использоваться для повышения конкурении в некоторых случаях использования некоторых типов коллекций. Это обычно стоит того только в том случае, если коллекции ожидаются большими, доступ к ним получают больше потоков-читателей, чем потоков-писателей, и операции требуют вычислений, которые перевешивают расходы на синхронизацию. Например, здесь представлен класс, использующий 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 в методах блокировки.

Since:
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 если для этого замка установлена справедливость

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, 2021, 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/17/docs/api/java.base/java/util/concurrent/locks/ReentrantReadWriteLock.html

Spec-Zone.ru

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