Класс StampedLock
- java.lang.Object
-
- java.util.concurrent.locks.StampedLock
- Все реализованные интерфейсы:
Serializable
public class StampedLock extends Object implements Serializable
Блокировка на основе возможностей с тремя режимами для управления чтением/записью. Состояние StampedLock состоит из версии и режима. Методы приобретения блокировки возвращают штамп, который представляет и управляет доступом относительно состояния блокировки; «попыточные» версии этих методов могут вместо этого вернуть специальное значение ноль, чтобы указать на неудачу в приобретении доступа. Методы освобождения и преобразования блокировки требуют штампов в качестве аргументов и завершаются неудачей, если они не соответствуют состоянию блокировки. Три режима следующие:
-
Запись. Метод
writeLock()может заблокироваться, ожидая эксклюзивного доступа, возвращая штамп, который может быть использован в методеunlockWrite(long)для освобождения блокировки. Также предоставляются неограниченные и ограниченные по времени версииtryWriteLock. Когда блокировка удерживается в режиме записи, получить блокировку чтения невозможно, и все оптимистичные проверки чтения завершатся неудачей. -
Чтение. Метод
readLock()может заблокироваться, ожидая неэксклюзивного доступа, возвращая штамп, который может быть использован в методеunlockRead(long)для освобождения блокировки. Также предоставляются неограниченные и ограниченные по времени версииtryReadLock. -
Оптимистическое чтение. Метод
tryOptimisticRead()возвращает ненулевой штамп только в том случае, если блокировка в данный момент не удерживается в режиме записи. Методvalidate(long)возвращает true, если блокировка не была приобретена в режиме записи с момента получения заданного штампа. Этот режим можно рассматривать как чрезвычайно слабую версию блокировки чтения, которая может быть прервана записывающим потоком в любое время. Использование оптимистического режима для коротких участков кода только для чтения часто уменьшает конфликтность и улучшает пропускную способность. Однако его использование изначально хрупко. Участки кода оптимистического чтения должны только читать поля и удерживать их в локальных переменных для последующего использования после проверки. Поля, прочитанные в оптимистическом режиме, могут быть сильно несовместимы, поэтому использование применимо только в том случае, если вы достаточно хорошо знакомы с представлениями данных для проверки согласованности и/или многократного вызова методаvalidate(). Например, такие шаги обычно необходимы при первоначальном чтении ссылки на объект или массив, а затем обращении к одному из его полей, элементов или методов.
Этот класс также поддерживает методы, которые условно предоставляют преобразования между тремя режимами. Например, метод tryConvertToWriteLock(long) пытается «обновить» режим, возвращая допустимый штамп записи, если (1) уже в режиме записи (2) в режиме чтения и нет других читателей или (3) в оптимистическом режиме и блокировка доступна. Формы этих методов разработаны для снижения некоторых избыточных кодов, которые в противном случае возникают в проектах, основанных на повторных попытках.
StampedLocks разработаны для использования в качестве внутренних утилит при разработке потокобезопасных компонентов. Их использование основано на знании внутренних свойств данных, объектов и методов, которые они защищают. Они не являются реентерабельными, поэтому блокируемые участки кода не должны вызывать другие неизвестные методы, которые могут пытаться повторно получить блокировки (хотя вы можете передать штамп другим методам, которые могут его использовать или преобразовать). Использование режимов блокировки чтения основано на том, что связанные участки кода не имеют побочных эффектов. Непроверенные участки оптимистического чтения не могут вызывать методы, которые не известны как способные переносить потенциальные несоответствия. Штампы используют конечные представления и не являются криптографически защищенными (т. е. допустимый штамп может быть угадан). Значения штампов могут перерабатываться через (не раньше) год непрерывной работы. Штамп, удерживаемый без использования или проверки в течение более длительного периода, может не пройти проверку. StampedLocks сериализуемы, но всегда десериализуются в начальное разблокированное состояние, поэтому они не подходят для удалённой блокировки.
Как и Semaphore, но в отличие от большинства реализаций Lock, StampedLocks не имеют понятия владения. Блокировки, полученные в одном потоке, могут быть освобождены или преобразованы в другом.
Политика планирования StampedLock не всегда отдаёт предпочтение читателям перед записывающими потоками или наоборот. Все методы «попытки» — это попытка, и они не обязательно соответствуют какой-либо политике планирования или справедливости. Возврат нуля от любого метода «попытки» для приобретения или преобразования блокировок не несёт никакой информации о состоянии блокировки; последующий вызов может быть успешным.
Поскольку он поддерживает скоординированное использование по нескольким режимам блокировки, этот класс не реализует напрямую интерфейсы Lock или ReadWriteLock. Однако в приложениях, требующих только соответствующего набора функциональности, StampedLock можно рассматривать как asReadLock(), asWriteLock() или asReadWriteLock().
Пример использования. Следующее иллюстрирует некоторые шаблоны использования в классе, который поддерживает простые двухмерные точки. Пример кода иллюстрирует некоторые соглашения try/catch, хотя они здесь строго не нужны, поскольку исключения не могут произойти в их телах.
class Point {
private double x, y;
private final StampedLock sl = new StampedLock();
// an exclusively locked method
void move(double deltaX, double deltaY) {
long stamp = sl.writeLock();
try {
x += deltaX;
y += deltaY;
} finally {
sl.unlockWrite(stamp);
}
}
// a read-only method
// upgrade from optimistic read to read lock
double distanceFromOrigin() {
long stamp = sl.tryOptimisticRead();
try {
retryHoldingLock: for (;; stamp = sl.readLock()) {
if (stamp == 0L)
continue retryHoldingLock;
// possibly racy reads
double currentX = x;
double currentY = y;
if (!sl.validate(stamp))
continue retryHoldingLock;
return Math.hypot(currentX, currentY);
}
} finally {
if (StampedLock.isReadLockStamp(stamp))
sl.unlockRead(stamp);
}
}
// upgrade from optimistic read to write lock
void moveIfAtOrigin(double newX, double newY) {
long stamp = sl.tryOptimisticRead();
try {
retryHoldingLock: for (;; stamp = sl.writeLock()) {
if (stamp == 0L)
continue retryHoldingLock;
// possibly racy reads
double currentX = x;
double currentY = y;
if (!sl.validate(stamp))
continue retryHoldingLock;
if (currentX != 0.0 || currentY != 0.0)
break;
stamp = sl.tryConvertToWriteLock(stamp);
if (stamp == 0L)
continue retryHoldingLock;
// exclusive access
x = newX;
y = newY;
return;
}
} finally {
if (StampedLock.isWriteLockStamp(stamp))
sl.unlockWrite(stamp);
}
}
// Upgrade read lock to write lock
void moveIfAtOrigin(double newX, double newY) {
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() | Опрашивает количество удерживаемых чтений для этого замка. |
static boolean | isLockStamp(long stamp) | Указывает, представляет ли штамп удержание замка. |
static boolean | isOptimisticReadStamp(long stamp) | Указывает, представляет ли штамп успешное оптимистическое чтение. |
boolean | isReadLocked() | Возвращает |
static boolean | isReadLockStamp(long stamp) | Указывает, представляет ли штамп удержание замка неисключительно. |
boolean | isWriteLocked() | Возвращает |
static boolean | isWriteLockStamp(long stamp) | Указывает, представляет ли штамп удержание замка исключительно. |
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если блокировка в настоящее время удерживается неисключительно
isWriteLockStamp
public static boolean isWriteLockStamp(long stamp)
Указывает, представляет ли метка удержание блокировки исключительно. Этот метод может быть полезен в сочетании с tryConvertToWriteLock(long), например:
long stamp = sl.tryOptimisticRead();
try {
...
stamp = sl.tryConvertToWriteLock(stamp);
...
} finally {
if (StampedLock.isWriteLockStamp(stamp))
sl.unlockWrite(stamp);
} - Параметры:
-
stamp- метка, возвращенная предыдущей операцией StampedLock - Возвращает:
-
trueесли метка была возвращена успешной операцией блокировки записи - С версии:
- 10
isReadLockStamp
public static boolean isReadLockStamp(long stamp)
Указывает, представляет ли метка удержание блокировки неисключительно. Этот метод может быть полезен в сочетании с tryConvertToReadLock(long), например:
long stamp = sl.tryOptimisticRead();
try {
...
stamp = sl.tryConvertToReadLock(stamp);
...
} finally {
if (StampedLock.isReadLockStamp(stamp))
sl.unlockRead(stamp);
} - Параметры:
-
stamp- метка, возвращенная предыдущей операцией StampedLock - Возвращает:
-
trueесли метка была возвращена успешной операцией блокировки чтения - С версии:
- 10
isLockStamp
public static boolean isLockStamp(long stamp)
Указывает, представляет ли метка удержание блокировки. Этот метод может быть полезен в сочетании с tryConvertToReadLock(long) и tryConvertToWriteLock(long), например:
long stamp = sl.tryOptimisticRead();
try {
...
stamp = sl.tryConvertToReadLock(stamp);
...
stamp = sl.tryConvertToWriteLock(stamp);
...
} finally {
if (StampedLock.isLockStamp(stamp))
sl.unlock(stamp);
} - Параметры:
-
stamp- метка, возвращенная предыдущей операцией StampedLock - Возвращает:
-
trueесли метка была возвращена успешной операцией блокировки чтения или записи - С версии:
- 10
isOptimisticReadStamp
public static boolean isOptimisticReadStamp(long stamp)
Указывает, представляет ли метка успешное оптимистичное чтение.
- Параметры:
-
stamp- метка, возвращенная предыдущей операцией StampedLock - Возвращает:
-
trueесли метка была возвращена успешной операцией оптимистичного чтения, то есть ненулевым результатом изtryOptimisticRead()илиtryConvertToOptimisticRead(long) - С версии:
- 10
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.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/locks/StampedLock.html