Spec-Zone.ru › OpenJDK 21

Класс 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, если замок не был получен в режиме записи с момента получения данного штампа, в этом случае все действия до последнего освобождения записи lock происходят до действий, следующих за вызовом 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)
Если состояние блокировки соответствует заданной марке, то атомарно, если марка представляет собой удержание блокировки, освобождает её и возвращает марку наблюдения. Или, если оптимистическое чтение, возвращает её, если она подтверждена. Этот метод возвращает ноль во всех остальных случаях, и поэтому может быть полезен как форма "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 если марка была возвращена успешной операцией получения записи блокировки
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);
 }
Параметры:
stamp - марка, возвращённая предыдущей операцией StampedLock
Возвращает:
true если марка была возвращена успешной операцией получения блокировки чтения
Since:
10
END_OF_DOCUMENT_MARKER

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, 2023, 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/21/docs/api/java.base/java/util/concurrent/locks/StampedLock.html

Spec-Zone.ru

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