Класс 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 | Блокировка, возвращаемая методом |
static class | ReentrantReadWriteLock.WriteLock | Блокировка, возвращаемая методом |
Конструкторы
| Конструктор | Описание |
|---|---|
ReentrantReadWriteLock() | Создает новую |
ReentrantReadWriteLock(boolean fair) | Создает новую |
Методы
| Модификатор и тип | Метод | Описание |
|---|---|---|
protected Thread | getOwner() | Возвращает поток, который в настоящее время владеет блокировкой записи, или |
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() | Возвращает |
boolean | isWriteLocked() | Запрашивает, удерживается ли блокировка записи каким-либо потоком. |
boolean | isWriteLockedByCurrentThread() | Запрашивает, удерживается ли блокировка записи текущим потоком. |
String | toString() | Возвращает строку, идентифицирующую эту блокировку, а также ее состояние блокировки. |
Методы, объявленные в классе java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait Методы, объявленные в интерфейсе java.util.concurrent.locks.ReadWriteLock
readLock, writeLock Конструкторы
ReentrantReadWriteLock
public ReentrantReadWriteLock()
Создаёт новый ReentrantReadWriteLock с порядком по умолчанию (не справедливый).
ReentrantReadWriteLock
public ReentrantReadWriteLock(boolean fair)
Создаёт новый ReentrantReadWriteLock с заданной политикой справедливости.
- Параметры:
-
fair-true, если для блокировки должна быть использована политика справедливого порядка
Методы
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 =" , за которой следует число удерживаемых блокировок чтения.
© 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.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/locks/ReentrantReadWriteLock.html