Класс StampedLock
- Все реализуемые интерфейсы:
Serializable
public class StampedLock extends Object implements Serializable
-
Запись. Метод
writeLock()может блокироваться в ожидании исключительного доступа и возвращает метку, которую можно использовать в методеunlockWrite(long)для освобождения блокировки. Также предусмотрены версииtryWriteLockбез ограничения времени и с ограничением времени. Когда блокировка удерживается в режиме записи, получить блокировки для чтения нельзя, а все проверки оптимистичного чтения завершаются неудачей. -
Чтение. Метод
readLock()может блокироваться в ожидании не исключительного доступа и возвращает метку, которую можно использовать в методеunlockRead(long)для освобождения блокировки. Также предусмотрены версииtryReadLockбез ограничения времени и с ограничением времени. -
Оптимистичное чтение. Метод
tryOptimisticRead()возвращает ненулевую метку, только если блокировка в данный момент не удерживается в режиме записи. Методvalidate(long)возвращает true, если после получения указанной метки блокировка не приобреталась в режиме записи; в этом случае все действия, предшествовавшие последнему освобождению блокировки записи, происходят до действий, следующих за вызовомtryOptimisticRead. Этот режим можно считать чрезвычайно слабой версией блокировки чтения, которую записывающий поток может прервать в любой момент. Использование оптимистичного режима чтения для коротких сегментов кода, выполняющих только чтение, часто уменьшает конкуренцию и повышает пропускную способность. Однако такое использование по своей природе ненадёжно. В оптимистичных секциях чтения следует только считывать поля и сохранять их в локальных переменных для последующего использования после проверки. Значения полей, считанные в оптимистичном режиме чтения, могут быть крайне противоречивыми, поэтому этот режим подходит только в том случае, если вы достаточно хорошо знакомы с представлением данных, чтобы проверять их согласованность и/или многократно вызывать методvalidate(). Например, такие действия обычно необходимы при первоначальном чтении ссылки на объект или массив с последующим обращением к одному из его полей, элементов или методов.
Этот класс также поддерживает методы, которые при определённых условиях преобразуют блокировку между тремя режимами. Например, метод tryConvertToWriteLock(long) пытается «повысить» режим, возвращая действительную метку записи, если (1) блокировка уже находится в режиме записи, (2) блокировка находится в режиме чтения и других читателей нет или (3) блокировка находится в оптимистичном режиме чтения и доступна. Формы этих методов призваны сократить избыточность кода, которая иначе возникает при использовании схем с повторными попытками.
StampedLock предназначены для использования в качестве внутренних служебных средств при разработке потокобезопасных компонентов. Их использование предполагает знание внутренних свойств защищаемых данных, объектов и методов. Они не являются реентерабельными, поэтому заблокированные участки кода не должны вызывать другие неизвестные методы, которые могут попытаться повторно получить блокировки (хотя метку можно передать другим методам, способным использовать её или преобразовать). Использование режимов блокировки чтения предполагает, что соответствующие участки кода не имеют побочных эффектов. Непроверенные оптимистичные секции чтения не могут вызывать методы, которые не гарантируют корректную работу при возможной несогласованности данных. Для меток используются представления конечной длины, и они не являются криптографически защищёнными (то есть действительную метку можно угадать). Значения меток могут повторно использоваться не ранее чем через год непрерывной работы. Метка, хранящаяся без использования или проверки дольше этого периода, может не пройти проверку корректно. StampedLock поддерживают сериализацию, но всегда десериализуются в исходное разблокированное состояние, поэтому не подходят для удалённой блокировки.
Как и Semaphore, но в отличие от большинства реализаций Lock, StampedLock не имеют понятия владения. Блокировки, полученные в одном потоке, могут быть освобождены или преобразованы в другом.
Политика планирования StampedLock не отдаёт постоянного предпочтения ни читателям, ни писателям. Все методы с префиксом «try» работают по принципу наилучших усилий и не обязательно соответствуют какой-либо политике планирования или справедливости. Возвращаемый любым методом «try» для получения или преобразования блокировок ноль не несёт никакой информации о состоянии блокировки; последующий вызов может завершиться успешно.
Поскольку этот класс поддерживает согласованное использование нескольких режимов блокировки, он напрямую не реализует интерфейсы Lock или ReadWriteLock. Однако в приложениях, которым нужен только соответствующий набор функций, StampedLock можно представить как asReadLock(), asWriteLock() или asReadWriteLock().
Синхронизация памяти. Методы, успешно блокирующие в любом режиме, имеют те же эффекты синхронизации памяти, что и действие Lock, описанное в главе 17 Спецификации языка Java. Методы, успешно освобождающие блокировку в режиме записи, имеют те же эффекты синхронизации памяти, что и действие Unlock. При использовании оптимистичного чтения действия, предшествующие последнему действию освобождения блокировки в режиме записи, гарантированно происходят до действий, следующих за tryOptimisticRead, только если последующий вызов validate возвращает true; в противном случае нет гарантии, что чтения между tryOptimisticRead и validate получают согласованный снимок.
Пример использования. Ниже показаны некоторые типичные способы использования в классе, который хранит простые двумерные точки. В примере кода демонстрируются некоторые соглашения 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 moveIfAtOrigin2(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);
}
}
}
- См. Спецификация языка Java:
- 17.4 Модель памяти
- Начиная с:
- 1.8
- См. также:
Краткое описание конструкторов
| Конструктор | Описание |
|---|---|
StampedLock() |
Создаёт новую блокировку, изначально находящуюся в разблокированном состоянии. |
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
Lock |
asReadLock() |
Возвращает представление этого StampedLock как обычную Lock, в котором метод Lock.lock() сопоставлен с readLock(), и аналогично для других методов. |
ReadWriteLock |
asReadWriteLock() |
Возвращает представление этого StampedLock как ReadWriteLock, в котором метод ReadWriteLock.readLock() сопоставлен с asReadLock(), а метод ReadWriteLock.writeLock() — с asWriteLock(). |
Lock |
asWriteLock() |
Возвращает представление этого StampedLock как обычную Lock, в котором метод Lock.lock() сопоставлен с writeLock(), и аналогично для других методов. |
int |
getReadLockCount() |
Возвращает число блокировок чтения, удерживаемых для этой блокировки. |
static boolean |
isLockStamp |
Показывает, представляет ли метка удержание блокировки. |
static boolean |
isOptimisticReadStamp |
Показывает, представляет ли метка успешное оптимистичное чтение. |
boolean |
isReadLocked() |
Возвращает true, если блокировка в данный момент удерживается не в исключительном режиме. |
static boolean |
isReadLockStamp |
Показывает, представляет ли метка удержание блокировки в не исключительном режиме. |
boolean |
isWriteLocked() |
Возвращает true, если блокировка в данный момент удерживается в исключительном режиме. |
static boolean |
isWriteLockStamp |
Показывает, представляет ли метка удержание блокировки в исключительном режиме. |
long |
readLock() |
Получает блокировку в не исключительном режиме, при необходимости блокируя выполнение до её освобождения. |
long |
readLockInterruptibly() |
Получает блокировку в не исключительном режиме, при необходимости блокируя выполнение до её освобождения или прерывания текущего потока. |
String |
toString() |
Возвращает строку, идентифицирующую эту блокировку и её состояние. |
long |
tryConvertToOptimisticRead |
Если состояние блокировки соответствует заданной метке, атомарно освобождает блокировку, если метка представляет её удержание, и возвращает метку наблюдения. |
long |
tryConvertToReadLock |
Если состояние блокировки соответствует заданной метке, атомарно выполняет одно из следующих действий. |
long |
tryConvertToWriteLock |
Если состояние блокировки соответствует заданной метке, атомарно выполняет одно из следующих действий. |
long |
tryOptimisticRead() |
Возвращает метку, которую можно проверить позднее, или ноль, если блокировка удерживается в исключительном режиме. |
long |
tryReadLock() |
Получает блокировку в не исключительном режиме, если она доступна немедленно. |
long |
tryReadLock |
Получает блокировку в не исключительном режиме, если она станет доступна в течение заданного времени и текущий поток не был прерван. |
boolean |
tryUnlockRead() |
Освобождает одно удержание блокировки чтения, если она удерживается, не требуя значения метки. |
boolean |
tryUnlockWrite() |
Освобождает блокировку записи, если она удерживается, не требуя значения метки. |
long |
tryWriteLock() |
Получает блокировку в исключительном режиме, если она доступна немедленно. |
long |
tryWriteLock |
Получает блокировку в исключительном режиме, если она станет доступна в течение заданного времени и текущий поток не был прерван. |
void |
unlock |
Если состояние блокировки соответствует заданной метке, освобождает соответствующий режим блокировки. |
void |
unlockRead |
Если состояние блокировки соответствует заданной метке, освобождает блокировку в не исключительном режиме. |
void |
unlockWrite |
Если состояние блокировки соответствует заданной метке, освобождает блокировку в исключительном режиме. |
boolean |
validate |
Возвращает true, если после выдачи заданной метки блокировка не получалась в исключительном режиме. |
long |
writeLock() |
Получает блокировку в исключительном режиме, при необходимости блокируя выполнение до её освобождения. |
long |
writeLockInterruptibly() |
Получает блокировку в исключительном режиме, при необходимости блокируя выполнение до её освобождения или прерывания текущего потока. |
Методы, объявленные в классе Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait | Модификатор и тип | Метод | Описание |
|---|---|---|
protected Object |
clone() |
Создаёт и возвращает копию этого объекта. |
boolean |
equals |
Показывает, равен ли этот объект какому-либо другому объекту. |
protected void |
finalize() |
Устарело, будет удалено: этот элемент API может быть удалён в будущей версии. Финализация объявлена устаревшей и будет удалена в одном из будущих выпусков. |
final Class |
getClass() |
Возвращает класс времени выполнения этого Object. |
int |
hashCode() |
Возвращает хеш-код этого объекта. |
final void |
notify() |
Пробуждает один поток, ожидающий на мониторе этого объекта. |
final void |
notifyAll() |
Пробуждает все потоки, ожидающие на мониторе этого объекта. |
final void |
wait() |
Заставляет текущий поток ожидать пробуждения, обычно посредством уведомления или прерывания. |
final void |
wait |
Заставляет текущий поток ожидать пробуждения, обычно посредством уведомления или прерывания, либо до истечения заданного времени. |
final void |
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)
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)
- Параметры:
-
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:", за которой следует текущее количество удерживаемых блокировок на чтение.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, 2025, 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.