Класс StampedLock
- java.lang.Object
-
- java.util.concurrent.locks.StampedLock
- Все реализованные интерфейсы:
- Serializable
public class StampedLock extends Object implements Serializable
Замок на основе возможностей с тремя режимами для управления доступом чтения/записи. Состояние StampedLock состоит из версии и режима. Методы получения замка возвращают штамп, который представляет и управляет доступом относительно состояния замка; версии "try" этих методов могут вместо этого возвращать специальное значение ноль, чтобы обозначить неудачу в получении доступа. Методы освобождения и преобразования замка требуют штампов в качестве аргументов и завершаются неудачей, если они не соответствуют состоянию замка. Три режима:
-
Запись. Метод
writeLock()может блокироваться, ожидая эксклюзивного доступа, возвращая штамп, который может использоваться в методеunlockWrite(long)для освобождения замка. Также предоставляются неблокируемые и блокируемые версииtryWriteLock. Когда замок удерживается в режиме записи, никакие замки чтения не могут быть получены, и все оптимистичные проверки чтения будут завершаться неудачей. -
Чтение. Метод
readLock()может блокироваться, ожидая неэксклюзивного доступа, возвращая штамп, который может использоваться в методеunlockRead(long)для освобождения замка. Также предоставляются неблокируемые и блокируемые версииtryReadLock. -
Оптимистичное чтение. Метод
tryOptimisticRead()возвращает ненулевой штамп только если замок в данный момент не удерживается в режиме записи. Методvalidate(long)возвращает true, если замок не был захвачен в режиме записи после получения данного штампа. Этот режим можно рассматривать как чрезвычайно слабую версию блокировки чтения, которую может сломать писатель в любое время. Использование оптимистичного режима для коротких сегментов кода только для чтения часто уменьшает конкуренцию и повышает производительность. Однако его использование по своей сути хрупко. Разделы оптимистичного чтения должны только читать поля и хранить их в локальных переменных для последующего использования после проверки. Поля, считываемые в оптимистичном режиме, могут быть сильно несогласованными, поэтому использование применяется только тогда, когда вы достаточно хорошо знакомы с представлениями данных, чтобы проверить согласованность и/или неоднократно вызывать методvalidate(). Например, такие шаги обычно требуются при первом чтении ссылки на объект или массив, а затем при доступе к одному из его полей, элементов или методов.
Этот класс также поддерживает методы, которые условно обеспечивают преобразования между тремя режимами. Например, метод tryConvertToWriteLock(long) пытается "обновить" режим, возвращая допустимый штамп записи, если (1) уже находится в режиме записи (2) в режиме чтения и нет других читателей или (3) в оптимистичном режиме и замок доступен. Формы этих методов предназначены для того, чтобы помочь уменьшить раздутие кода, которое в противном случае происходит в конструкциях на основе повторных попыток.
StampedLocks предназначены для использования в качестве внутренних утилит при разработке потокобезопасных компонентов. Их использование основано на знании внутренних свойств данных, объектов и методов, которые они защищают. Они не являются реентерабельными, поэтому заблокированные блоки не должны вызывать другие неизвестные методы, которые могут попытаться повторно получить замки (хотя вы можете передать штамп другим методам, которые могут использовать или преобразовывать его). Использование режимов блокировки чтения основано на том, что связанные разделы кода не имеют побочных эффектов. Непроверенные оптимистичные разделы чтения не могут вызывать методы, которые не известны как терпимые к потенциальным несоответствиям. Штампы используют конечные представления и не являются криптографически защищенными (т.е. допустимый штамп может быть угадан). Значения штампов могут перерабатываться через (не раньше чем) один год непрерывной работы. Штамп, удерживаемый без использования или проверки дольше этого периода, может не пройти проверку правильно. StampedLocks сериализуемы, но всегда десериализуются в исходное незаблокированное состояние, поэтому они не подходят для удаленной блокировки.
Политика планирования StampedLock не всегда отдает предпочтение читателям перед писателями или наоборот. Все методы "try" являются наилучшими усилиями и не обязательно соответствуют какой-либо политике планирования или справедливости. Нулевой возврат любого метода "try" для получения или преобразования замков не содержит никакой информации о состоянии замка; последующий вызов может завершиться успешно.
Поскольку он поддерживает скоординированное использование в нескольких режимах блокировки, этот класс не напрямую реализует интерфейсы Lock или ReadWriteLock. Однако StampedLock может рассматриваться asReadLock(), asWriteLock() или asReadWriteLock() в приложениях, требующих только связанного набора функциональности.
Пример использования. Ниже показаны некоторые идиомы использования в классе, который поддерживает простые двумерные точки. Пример кода иллюстрирует некоторые соглашения try/catch, хотя они здесь строго не нужны, потому что в их телах не может возникнуть никаких исключений.
class Point {
private double x, y;
private final StampedLock sl = new StampedLock();
void move(double deltaX, double deltaY) { // an exclusively locked method
long stamp = sl.writeLock();
try {
x += deltaX;
y += deltaY;
} finally {
sl.unlockWrite(stamp);
}
}
double distanceFromOrigin() { // A read-only method
long stamp = sl.tryOptimisticRead();
double currentX = x, currentY = y;
if (!sl.validate(stamp)) {
stamp = sl.readLock();
try {
currentX = x;
currentY = y;
} finally {
sl.unlockRead(stamp);
}
}
return Math.sqrt(currentX * currentX + currentY * currentY);
}
void moveIfAtOrigin(double newX, double newY) { // upgrade
// Could instead start with optimistic, not read mode
long stamp = sl.readLock();
try {
while (x == 0.0 && y == 0.0) {
long ws = sl.tryConvertToWriteLock(stamp);
if (ws != 0L) {
stamp = ws;
x = newX;
y = newY;
break;
}
else {
sl.unlockRead(stamp);
stamp = sl.writeLock();
}
}
} finally {
sl.unlock(stamp);
}
}
}
- С момента:
- 1.8
- См. также:
- Сериализованная форма
Краткое описание конструкторов
| Конструктор и описание |
|---|
StampedLock() Создает новый замок, первоначально в незаблокированном состоянии. |
Краткое описание методов
| Модификатор и тип | Метод и описание |
|---|---|
Lock |
asReadLock() Возвращает простой просмотр |
ReadWriteLock |
asReadWriteLock() Возвращает представление |
Lock |
asWriteLock() Возвращает простой просмотр |
int |
getReadLockCount() Запрашивает количество удерживаемых блокировок чтения для этого замка. |
boolean |
isReadLocked() Возвращает |
boolean |
isWriteLocked() Возвращает |
long |
readLock() Неисключительно приобретает замок, блокируя при необходимости до тех пор, пока он не станет доступен. |
long |
readLockInterruptibly() Неисключительно приобретает замок, блокируя при необходимости до тех пор, пока он не станет доступен или текущий поток не будет прерван. |
String |
toString() Возвращает строку, идентифицирующую этот замок, а также его состояние блокировки. |
long |
tryConvertToOptimisticRead(long stamp) Если состояние замка соответствует заданному штампу, то, если штамп представляет собой удержание замка, освобождает его и возвращает штамп наблюдения. |
long |
tryConvertToReadLock(long stamp) Если состояние замка соответствует заданному штампу, выполняет одно из следующих действий. |
long |
tryConvertToWriteLock(long stamp) Если состояние замка соответствует заданному штампу, выполняет одно из следующих действий. |
long |
tryOptimisticRead() Возвращает штамп, который может быть позже проверен, или ноль, если заблокирован исключительно. |
long |
tryReadLock() Неисключительно приобретает замок, если он немедленно доступен. |
long |
tryReadLock(long time,
TimeUnit unit) Неисключительно приобретает замок, если он доступен в течение заданного времени и текущий поток не был прерван. |
boolean |
tryUnlockRead() Освобождает одно удержание блокировки чтения, если она удерживается, без требования значения штампа. |
boolean |
tryUnlockWrite() Освобождает блокировку записи, если она удерживается, без требования значения штампа. |
long |
tryWriteLock() Исключительно приобретает замок, если он немедленно доступен. |
long |
tryWriteLock(long time,
TimeUnit unit) Исключительно приобретает замок, если он доступен в течение заданного времени и текущий поток не был прерван. |
void |
unlock(long stamp) Если состояние замка соответствует заданному штампу, освобождает соответствующий режим замка. |
void |
unlockRead(long stamp) Если состояние замка соответствует заданному штампу, освобождает неисключительный замок. |
void |
unlockWrite(long stamp) Если состояние замка соответствует заданному штампу, освобождает исключительный замок. |
boolean |
validate(long stamp) Возвращает true, если замок не был исключительно захвачен с момента выдачи заданного штампа. |
long |
writeLock() Исключительно приобретает замок, блокируя при необходимости до тех пор, пока он не станет доступен. |
long |
writeLockInterruptibly() Исключительно приобретает замок, блокируя при необходимости до тех пор, пока он не станет доступен или текущий поток не будет прерван. |
Методы, унаследованные от класса java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait Конструкторы
StampedLock
public StampedLock()
Создаёт новый замок, первоначально в разблокированном состоянии.
Методы
writeLock
public long writeLock()
Исключительно приобретает замок, блокируя при необходимости до тех пор, пока он не станет доступным.
- Возвращает:
- штамп, который можно использовать для разблокировки или изменения режима
tryWriteLock
public long tryWriteLock()
Исключительно приобретает замок, если он сразу же доступен.
- Возвращает:
- штамп, который можно использовать для разблокировки или изменения режима, или ноль, если замок недоступен
tryWriteLock
public long tryWriteLock(long time,
TimeUnit unit)
throws InterruptedException Исключительно приобретает замок, если он доступен в течение заданного времени и текущий поток не был прерван. Поведение при истечении времени ожидания и прерывании соответствует указанному для метода Lock.tryLock(long,TimeUnit).
- Параметры:
-
time- максимальное время ожидания замка -
unit- единица измерения времени аргументаtime - Возвращает:
- штамп, который можно использовать для разблокировки или изменения режима, или ноль, если замок недоступен
- Исключения:
-
InterruptedException- если текущий поток прерван до получения замка
writeLockInterruptibly
public long writeLockInterruptibly()
throws InterruptedException Исключительно приобретает замок, блокируя при необходимости до тех пор, пока он не станет доступным или текущий поток не будет прерван. Поведение при прерывании соответствует указанному для метода Lock.lockInterruptibly().
- Возвращает:
- штамп, который можно использовать для разблокировки или изменения режима
- Исключения:
-
InterruptedException- если текущий поток прерван до получения замка
readLock
public long readLock()
Неисключительно приобретает замок, блокируя при необходимости до тех пор, пока он не станет доступным.
- Возвращает:
- штамп, который можно использовать для разблокировки или изменения режима
tryReadLock
public long tryReadLock()
Неисключительно приобретает замок, если он сразу же доступен.
- Возвращает:
- штамп, который можно использовать для разблокировки или изменения режима, или ноль, если замок недоступен
tryReadLock
public long tryReadLock(long time,
TimeUnit unit)
throws InterruptedException Неисключительно приобретает замок, если он доступен в течение заданного времени и текущий поток не был прерван. Поведение при истечении времени ожидания и прерывании соответствует указанному для метода Lock.tryLock(long,TimeUnit).
- Параметры:
-
time- максимальное время ожидания замка -
unit- единица измерения времени аргументаtime - Возвращает:
- штамп, который можно использовать для разблокировки или изменения режима, или ноль, если замок недоступен
- Исключения:
-
InterruptedException- если текущий поток прерван до получения замка
readLockInterruptibly
public long readLockInterruptibly()
throws InterruptedException Неисключительно приобретает замок, блокируя при необходимости до тех пор, пока он не станет доступным или текущий поток не будет прерван. Поведение при прерывании соответствует указанному для метода Lock.lockInterruptibly().
- Возвращает:
- штамп, который можно использовать для разблокировки или изменения режима
- Исключения:
-
InterruptedException- если текущий поток прерван до получения замка
tryOptimisticRead
public long tryOptimisticRead()
Возвращает штамп, который позже можно проверить, или ноль, если замок заблокирован исключительно.
- Возвращает:
- штамп или ноль, если замок заблокирован исключительно
validate
public boolean validate(long stamp)
Возвращает true, если замок не был заблокирован исключительно с момента выдачи данного штампа. Всегда возвращает false, если штамп равен нулю. Всегда возвращает true, если штамп представляет текущий удерживаемый замок. Вызов этого метода со значением, не полученным из tryOptimisticRead() или метода блокировки для этого замка, не имеет определенного эффекта или результата.
- Параметры:
-
stamp- штамп - Возвращает:
-
trueесли замок не был заблокирован исключительно с момента выдачи данного штампа; иначе false
unlockWrite
public void unlockWrite(long stamp)
Если состояние замка соответствует заданному штампу, разблокирует исключительный замок.
- Параметры:
-
stamp- штамп, возвращённый операцией блокировки записи - Исключения:
-
IllegalMonitorStateException- если штамп не соответствует текущему состоянию этого замка
unlockRead
public void unlockRead(long stamp)
Если состояние замка соответствует заданному штампу, разблокирует неисключительный замок.
- Параметры:
-
stamp- штамп, возвращённый операцией блокировки чтения - Исключения:
-
IllegalMonitorStateException- если штамп не соответствует текущему состоянию этого замка
unlock
public void unlock(long stamp)
Если состояние замка соответствует заданному штампу, разблокирует соответствующий режим замка.
- Параметры:
-
stamp- штамп, возвращённый операцией блокировки - Исключения:
-
IllegalMonitorStateException- если штамп не соответствует текущему состоянию этого замка
tryConvertToWriteLock
public long tryConvertToWriteLock(long stamp)
Если состояние замка соответствует заданному штампу, выполняет одно из следующих действий. Если штамп представляет удержание записи, возвращает его. Или, если чтение, если запись доступна, разблокирует чтение и возвращает штамп записи. Или, если оптимистическое чтение, возвращает штамп записи только если он сразу доступен. Этот метод возвращает ноль во всех остальных случаях.
- Параметры:
-
stamp- штамп - Возвращает:
- действительный штамп записи или ноль в случае неудачи
tryConvertToReadLock
public long tryConvertToReadLock(long stamp)
Если состояние замка соответствует заданному штампу, выполняет одно из следующих действий. Если штамп представляет удержание записи, разблокирует её и получает чтение. Или, если чтение, возвращает его. Или, если оптимистическое чтение, приобретает чтение и возвращает штамп чтения только если он сразу же доступен. Этот метод возвращает ноль во всех остальных случаях.
- Параметры:
-
stamp- штамп - Возвращает:
- действительный штамп чтения или ноль в случае неудачи
tryConvertToOptimisticRead
public long tryConvertToOptimisticRead(long stamp)
Если состояние замка соответствует заданному штампу, если штамп представляет удержание замка, разблокирует его и возвращает штамп наблюдения. Или, если оптимистическое чтение, возвращает его, если проверка пройдена. Этот метод возвращает ноль во всех остальных случаях, и поэтому может быть полезен в качестве формы "tryUnlock".
- Параметры:
-
stamp- штамп - Возвращает:
- действительный штамп оптимистического чтения или ноль в случае неудачи
tryUnlockWrite
public boolean tryUnlockWrite()
Разблокирует замок записи, если он удерживается, без необходимости значения штампа. Этот метод может быть полезен для восстановления после ошибок.
- Возвращает:
-
trueесли замок был удерживаем, иначе false
tryUnlockRead
public boolean tryUnlockRead()
Разблокирует одну блокировку чтения, если она удерживается, без требования значения штампа. Этот метод может быть полезен для восстановления после ошибок.
- Возвращает:
-
trueесли блокировка чтения была удерживаема, иначе false
isWriteLocked
public boolean isWriteLocked()
Возвращает true если замок в настоящее время удерживается исключительно.
- Возвращает:
-
trueесли замок в настоящее время удерживается исключительно
isReadLocked
public boolean isReadLocked()
Возвращает true если замок в настоящее время удерживается неисключительно.
- Возвращает:
-
trueесли замок в настоящее время удерживается неисключительно
getReadLockCount
public int getReadLockCount()
Запрашивает количество блокировок чтения, удерживаемых для этого замка. Этот метод предназначен для использования в мониторинге состояния системы, а не для управления синхронизацией.
- Возвращает:
- количество удерживаемых блокировок чтения
toString
public String toString()
Возвращает строку, идентифицирующую этот замок, а также его состояние. Состояние, в скобках, включает строку "Unlocked" или строку "Write-locked" или строку "Read-locks:" за которой следует текущее количество удерживаемых блокировок чтения.
- Переопределяет:
-
toStringв классеObject - Возвращает:
- строку, идентифицирующую этот замок, а также его состояние
asReadLock
public Lock asReadLock()
Возвращает обычный вид Lock этого StampedLock, в котором метод Lock.lock() сопоставлен с readLock(), и аналогично для других методов. Возвращённый Lock не поддерживает метод Condition; метод Lock.newCondition() вызывает исключение UnsupportedOperationException.
- Возвращает:
- замок
asWriteLock
public Lock asWriteLock()
Возвращает обычный вид Lock этого StampedLock, в котором метод Lock.lock() сопоставлен с writeLock(), и аналогично для других методов. Возвращённый Lock не поддерживает метод Condition; метод Lock.newCondition() вызывает исключение UnsupportedOperationException.
- Возвращает:
- замок
asReadWriteLock
public ReadWriteLock asReadWriteLock()
Возвращает вид ReadWriteLock этого StampedLock, в котором метод ReadWriteLock.readLock() сопоставлен с asReadLock(), а ReadWriteLock.writeLock() с asWriteLock().
- Возвращает:
- замок
© 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.