Spec-Zone.ru › OpenJDK 8

Класс 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;
   volatile 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<String, Data>();
   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 String[] allKeys() {
     r.lock();
     try { return m.keySet().toArray(); }
     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()

Возвращает коллекцию, содержащую потоки, которые могут ожидать приобретения блокировки для записи.

int getQueueLength()

Возвращает приблизительное количество потоков, ожидающих приобретения блокировки для чтения или записи.

int getReadHoldCount()

Запрашивает количество рекурсивных удержаний блокировки для чтения текущим потоком.

int getReadLockCount()

Запрашивает количество удерживаемых блокировок для чтения.

protected Collection<Thread> getWaitingThreads(Condition condition)

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

int getWaitQueueLength(Condition condition)

Возвращает приблизительное количество потоков, ожидающих условия, связанного с блокировкой для записи.

int getWriteHoldCount()

Запрашивает количество рекурсивных удержаний блокировки для записи текущим потоком.

boolean hasQueuedThread(Thread thread)

Запрашивает, ожидает ли указанный поток приобретения блокировки для чтения или записи.

boolean hasQueuedThreads()

Запрашивает, ожидают ли какие-либо потоки приобретения блокировки для чтения или записи.

boolean hasWaiters(Condition condition)

Запрашивает, ожидают ли какие-либо потоки условия, связанного с блокировкой для записи.

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 =" за которой следует количество удерживаемых блокировок чтения.

Переопределяет:
toString в классе Object
Возвращает:
строка, идентифицирующая этот замок, а также его состояние

© 1993, 2020, 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