Spec-Zone.ru › OpenJDK 17

Класс 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)
Если состояние замка соответствует заданной марке, то атомарно, если марка представляет собой удержание замка, освобождает его и возвращает марку наблюдения. Или, если оптимистическое чтение, возвращает его, если он проверен. В остальных случаях метод возвращает ноль, и поэтому может быть полезен как форма «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

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(), и аналогично для других методов. Возвращаемая блокировка не поддерживает метод Condition; метод Lock.newCondition() вызывает UnsupportedOperationException.
Returns:
блокировку

asWriteLock

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

asReadWriteLock

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

© 1993, 2021, 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/17/docs/api/java.base/java/util/concurrent/locks/StampedLock.html

Spec-Zone.ru

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