Spec-Zone.ru › OpenJDK 24

Класс 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, если блокировка не была приобретена в режиме записи с момента получения данного штампа, в этом случае все действия до последнего освобождения блокировки записи происходят до действий, следующих за вызовом tryOptimisticRead. Этот режим можно рассматривать как чрезвычайно слабую версию блокировки чтения, которая может быть прервана записывающим потоком в любое время. Использование режима оптимистического чтения для коротких участков кода только для чтения часто снижает конфликтность и повышает пропускную способность. Однако его использование по своей природе хрупкое. Участки кода оптимистического чтения должны только считывать поля и удерживать их в локальных переменных для последующего использования после проверки. Поля, прочитанные в режиме оптимистического чтения, могут быть сильно несовместимы, поэтому использование применяется только тогда, когда вы достаточно знакомы с представлениями данных, чтобы проверить согласованность и/или многократно вызывать метод validate(). Например, такие шаги обычно требуются при первом чтении ссылки на объект или массив, а затем доступе к одному из его полей, элементов или методов.

Этот класс также поддерживает методы, которые условно обеспечивают преобразования между тремя режимами. Например, метод tryConvertToWriteLock(long) пытается "обновить" режим, возвращая действительный штамп записи, если (1) уже в режиме записи (2) в режиме чтения и нет других читателей или (3) в режиме оптимистического чтения и блокировка доступна. Формы этих методов предназначены для уменьшения некоторого надувания кода, которое в противном случае происходит в проектах, основанных на повторных попытках.

StampedLocks разработаны для использования в качестве внутренних утилит при разработке потокобезопасных компонентов. Их использование основано на знаниях внутренних свойств данных, объектов и методов, которые они защищают. Они не являются реентерабельными, поэтому заблокированные тела не должны вызывать другие неизвестные методы, которые могут пытаться повторно приобрести блокировки (хотя вы можете передать штамп другим методам, которые могут использовать или преобразовывать его). Использование режимов блокировки чтения основано на том, что соответствующие разделы кода не имеют побочных эффектов. Невалидированные участки оптимистического чтения не могут вызывать методы, которые не известны, чтобы они могли терпеть потенциальные несогласованности. Штампы используют конечные представления и не являются криптографически защищенными (т.е., действительный штамп может быть угадан). Значения штампов могут циклически повторно использоваться после (не ранее) одного года непрерывной работы. Штамп, удерживаемый без использования или проверки в течение более длительного периода, может не пройти проверку правильно. StampedLocks сериализуемы, но всегда десериализуются в первоначальное разблокированное состояние, поэтому они не подходят для удаленного блокирования.

Подобно Semaphore, но в отличие от большинства реализаций Lock, StampedLocks не имеют понятия владения. Блокировки, приобретенные в одном потоке, могут быть освобождены или преобразованы в другом.

Политика планирования StampedLock не последовательно отдаёт предпочтение читателям над писателями или наоборот. Все методы "попытки" являются наилучшими усилиями и не обязательно соответствуют какой-либо политике планирования или справедливости. Возвращение нуля от любого метода "попытки" для приобретения или преобразования блокировок не несёт никакой информации о состоянии блокировки; последующий вызов может быть успешным.

Поскольку он поддерживает скоординированное использование в нескольких режимах блокировки, этот класс напрямую не реализует интерфейсы Lock или ReadWriteLock. Однако, StampedLock может быть рассмотрен asReadLock(), asWriteLock() или asReadWriteLock() в приложениях, требующих только соответствующего набора функциональности.

Синхронизация памяти. Методы, имеющие эффект успешного блокирования в любом режиме, имеют те же эффекты синхронизации памяти, что и действие Lock, как описано в главе 17 спецификации языка Java. Методы успешного разблокирования в режиме записи имеют те же эффекты синхронизации памяти, что и действие Unlock. При использовании оптимистического чтения действия до последнего действия разблокировки в режиме записи гарантированно происходят до действий, следующих за tryOptimisticRead, только если последующая проверка возвращает 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()
Возвращает простой Lock вид этого StampedLock, в котором метод Lock.lock() сопоставлен с readLock(), и аналогично для других методов.
ReadWriteLock asReadWriteLock()
Возвращает ReadWriteLock вид этого StampedLock, в котором метод ReadWriteLock.readLock() сопоставлен с asReadLock(), а ReadWriteLock.writeLock() с asWriteLock().
Lock asWriteLock()
Возвращает простой Lock вид этого StampedLock, в котором метод Lock.lock() сопоставлен с writeLock(), и аналогично для других методов.
int getReadLockCount()
Опрашивает количество захваченных чтений для этого замка.
static boolean isLockStamp(long stamp)
Указывает, представляет ли штамп удержание замка.
static boolean isOptimisticReadStamp(long stamp)
Указывает, представляет ли штамп успешное оптимистическое чтение.
boolean isReadLocked()
Возвращает true, если замок в настоящее время удерживается неисключительно.
static boolean isReadLockStamp(long stamp)
Указывает, представляет ли штамп удержание замка неисключительно.
boolean isWriteLocked()
Возвращает true, если замок в настоящее время удерживается исключительно.
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)
Если состояние блокировки соответствует заданному штампу, то атомарно, если штамп представляет собой удержание блокировки, освобождает ее и возвращает штамп наблюдения. Или, если оптимистическое чтение, возвращает его, если он подтвержден. Этот метод возвращает ноль во всех остальных случаях, и поэтому может быть полезен в качестве формы «попытки разблокировки».
Параметры:
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);
 }
Parameters:
stamp - штамп, возвращённый предыдущей операцией StampedLock
Returns:
true если штамп был возвращён успешной операцией взятия записи блокировки
Since:
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);
 }
Parameters:
stamp - штамп, возвращённый предыдущей операцией StampedLock
Returns:
true если штамп был возвращён успешной операцией взятия блокировки для чтения
Since:
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);
 }
Parameters:
stamp - штамп, возвращённый предыдущей операцией StampedLock
Returns:
true если штамп был возвращён успешной операцией взятия блокировки для чтения или записи
Since:
10

isOptimisticReadStamp

public static boolean isOptimisticReadStamp(long stamp)
Определяет, представляет ли штамп успешное оптимистическое чтение.
Parameters:
stamp - штамп, возвращённый предыдущей операцией StampedLock
Returns:
true если штамп был возвращён успешной операцией оптимистического чтения, то есть, ненулевым результатом от tryOptimisticRead() или tryConvertToOptimisticRead(long)
Since:
10

getReadLockCount

public int getReadLockCount()
Запрашивает количество блокировок для чтения, удерживаемых для этой блокировки. Этот метод предназначен для использования при мониторинге состояния системы, а не для управления синхронизацией.
Returns:
количество удерживаемых блокировок для чтения

toString

public String toString()
Возвращает строку, идентифицирующую эту блокировку, а также её состояние. Состояние, в скобках, включает строку "Unlocked" или строку "Write-locked" или строку "Read-locks:", за которой следует текущее количество удерживаемых блокировок для чтения.
Overrides:
toString в классе Object
Returns:
строку, идентифицирующую эту блокировку, а также её состояние

asReadLock

public Lock asReadLock()
Возвращает простой вид Lock этой StampedLock, в котором метод Lock.lock() отображается на readLock(), и аналогично для других методов. Возвращаемый Lock не поддерживает метод Condition; метод Lock.newCondition() вызывает исключение UnsupportedOperationException.
Returns:
блокировку

asWriteLock

public Lock asWriteLock()
Возвращает простой вид Lock этой StampedLock, в котором метод Lock.lock() отображается на writeLock(), и аналогично для других методов. Возвращаемый Lock не поддерживает метод Condition; метод Lock.newCondition() вызывает исключение UnsupportedOperationException.
Returns:
блокировку

asReadWriteLock

public ReadWriteLock asReadWriteLock()
Возвращает вид ReadWriteLock этой StampedLock, в котором метод ReadWriteLock.readLock() отображается на asReadLock(), и ReadWriteLock.writeLock() на asWriteLock().
Returns:
блокировку

© 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.
https://download.java.net/java/early_access/jdk24/docs/api/java.base/java/util/concurrent/locks/StampedLock.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API