Класс StampedLock

Все реализованные интерфейсы:
Serializable
public class StampedLock
extends Object
implements Serializable

Блокировка на основе возможностей с тремя режимами для управления чтением/записью. Состояние StampedLock состоит из версии и режима. Методы приобретения блокировки возвращают штамп, который представляет и управляет доступом относительно состояния блокировки; «попыточные» версии этих методов могут вместо этого вернуть специальное значение ноль, чтобы указать на неудачу в приобретении доступа. Методы освобождения и преобразования блокировки требуют штампов в качестве аргументов и завершаются неудачей, если они не соответствуют состоянию блокировки. Три режима следующие:

  • Запись. Метод writeLock() может заблокироваться, ожидая эксклюзивного доступа, возвращая штамп, который может быть использован в методе unlockWrite(long) для освобождения блокировки. Также предоставляются неограниченные и ограниченные по времени версии tryWriteLock. Когда блокировка удерживается в режиме записи, получить блокировку чтения невозможно, и все оптимистичные проверки чтения завершатся неудачей.
  • Чтение. Метод readLock() может заблокироваться, ожидая неэксклюзивного доступа, возвращая штамп, который может быть использован в методе unlockRead(long) для освобождения блокировки. Также предоставляются неограниченные и ограниченные по времени версии tryReadLock.
  • Оптимистическое чтение. Метод tryOptimisticRead() возвращает ненулевой штамп только в том случае, если блокировка в данный момент не удерживается в режиме записи. Метод validate(long) возвращает true, если блокировка не была приобретена в режиме записи с момента получения заданного штампа. Этот режим можно рассматривать как чрезвычайно слабую версию блокировки чтения, которая может быть прервана записывающим потоком в любое время. Использование оптимистического режима для коротких участков кода только для чтения часто уменьшает конфликтность и улучшает пропускную способность. Однако его использование изначально хрупко. Участки кода оптимистического чтения должны только читать поля и удерживать их в локальных переменных для последующего использования после проверки. Поля, прочитанные в оптимистическом режиме, могут быть сильно несовместимы, поэтому использование применимо только в том случае, если вы достаточно хорошо знакомы с представлениями данных для проверки согласованности и/или многократного вызова метода validate(). Например, такие шаги обычно необходимы при первоначальном чтении ссылки на объект или массив, а затем обращении к одному из его полей, элементов или методов.

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

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

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

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

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

Пример использования. Следующее иллюстрирует некоторые шаблоны использования в классе, который поддерживает простые двухмерные точки. Пример кода иллюстрирует некоторые соглашения try/catch, хотя они здесь строго не нужны, поскольку исключения не могут произойти в их телах.

class Point {
   private double x, y;
   private final StampedLock sl = new StampedLock();

   // an exclusively locked method
   void move(double deltaX, double deltaY) {
     long stamp = sl.writeLock();
     try {
       x += deltaX;
       y += deltaY;
     } finally {
       sl.unlockWrite(stamp);
     }
   }

   // a read-only method
   // upgrade from optimistic read to read lock
   double distanceFromOrigin() {
     long stamp = sl.tryOptimisticRead();
     try {
       retryHoldingLock: for (;; stamp = sl.readLock()) {
         if (stamp == 0L)
           continue retryHoldingLock;
         // possibly racy reads
         double currentX = x;
         double currentY = y;
         if (!sl.validate(stamp))
           continue retryHoldingLock;
         return Math.hypot(currentX, currentY);
       }
     } finally {
       if (StampedLock.isReadLockStamp(stamp))
         sl.unlockRead(stamp);
     }
   }

   // upgrade from optimistic read to write lock
   void moveIfAtOrigin(double newX, double newY) {
     long stamp = sl.tryOptimisticRead();
     try {
       retryHoldingLock: for (;; stamp = sl.writeLock()) {
         if (stamp == 0L)
           continue retryHoldingLock;
         // possibly racy reads
         double currentX = x;
         double currentY = y;
         if (!sl.validate(stamp))
           continue retryHoldingLock;
         if (currentX != 0.0 || currentY != 0.0)
           break;
         stamp = sl.tryConvertToWriteLock(stamp);
         if (stamp == 0L)
           continue retryHoldingLock;
         // exclusive access
         x = newX;
         y = newY;
         return;
       }
     } finally {
       if (StampedLock.isWriteLockStamp(stamp))
         sl.unlockWrite(stamp);
     }
   }

   // Upgrade read lock to write lock
   void moveIfAtOrigin(double newX, double newY) {
     long stamp = sl.readLock();
     try {
       while (x == 0.0 && y == 0.0) {
         long ws = sl.tryConvertToWriteLock(stamp);
         if (ws != 0L) {
           stamp = ws;
           x = newX;
           y = newY;
           break;
         }
         else {
           sl.unlockRead(stamp);
           stamp = sl.writeLock();
         }
       }
     } finally {
       sl.unlock(stamp);
     }
   }
 }
С момента:
1.8
См. также:
Сериализованная форма

Конструкторы

Конструктор Описание
StampedLock()

Создаёт новую блокировку, первоначально в разблокированном состоянии.

Методы

Модификатор и тип Метод Описание
Lock asReadLock()

Возвращает обычный 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 если метка была возвращена успешной операцией блокировки записи
С версии:
10

isReadLockStamp

public static boolean isReadLockStamp(long stamp)

Указывает, представляет ли метка удержание блокировки неисключительно. Этот метод может быть полезен в сочетании с tryConvertToReadLock(long), например:

long stamp = sl.tryOptimisticRead();
 try {
   ...
   stamp = sl.tryConvertToReadLock(stamp);
   ...
 } finally {
   if (StampedLock.isReadLockStamp(stamp))
     sl.unlockRead(stamp);
 }

Параметры:
stamp - метка, возвращенная предыдущей операцией StampedLock
Возвращает:
true если метка была возвращена успешной операцией блокировки чтения
С версии:
10

isLockStamp

public static boolean isLockStamp(long stamp)

Указывает, представляет ли метка удержание блокировки. Этот метод может быть полезен в сочетании с tryConvertToReadLock(long) и tryConvertToWriteLock(long), например:

long stamp = sl.tryOptimisticRead();
 try {
   ...
   stamp = sl.tryConvertToReadLock(stamp);
   ...
   stamp = sl.tryConvertToWriteLock(stamp);
   ...
 } finally {
   if (StampedLock.isLockStamp(stamp))
     sl.unlock(stamp);
 }

Параметры:
stamp - метка, возвращенная предыдущей операцией StampedLock
Возвращает:
true если метка была возвращена успешной операцией блокировки чтения или записи
С версии:
10

isOptimisticReadStamp

public static boolean isOptimisticReadStamp(long stamp)

Указывает, представляет ли метка успешное оптимистичное чтение.

Параметры:
stamp - метка, возвращенная предыдущей операцией StampedLock
Возвращает:
true если метка была возвращена успешной операцией оптимистичного чтения, то есть ненулевым результатом из tryOptimisticRead() или tryConvertToOptimisticRead(long)
С версии:
10

getReadLockCount

public int getReadLockCount()

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

Возвращает:
количество удерживаемых блокировок чтения

toString

public String toString()

Возвращает строку, идентифицирующую эту блокировку, а также ее состояние блокировки. Состояние, в скобках, включает строку "Unlocked" или строку "Write-locked" или строку "Read-locks:" с последующим текущим количеством удерживаемых блокировок чтения.

Переопределяет:
toString в классе Object
Возвращает:
строку, идентифицирующую этот замок, а также его состояние

asReadLock

public Lock asReadLock()

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

Возвращает:
замок

asWriteLock

public Lock asWriteLock()

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

Возвращает:
замок

asReadWriteLock

public ReadWriteLock asReadWriteLock()

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

Возвращает:
замок

© 1993, 2020, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/locks/StampedLock.html

Spec-Zone .ru
спецификации, руководства, описания, API