Класс ReentrantLock

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

Рекурсивный взаимный исключающий Lock с тем же базовым поведением и семантикой, что и неявный мониторный замок, доступный с помощью synchronized методов и операторов, но с расширенными возможностями.

ReentrantLock владеет потоком, последний успешно его заблокировавший, но еще не разблокировавший. Поток, вызывающий lock, вернётся, успешно получив замок, когда замок не владеет другим потоком. Метод вернётся немедленно, если текущий поток уже владеет замком. Это можно проверить с помощью методов isHeldByCurrentThread() и getHoldCount().

Конструктор этого класса принимает необязательный параметр честности. При установке true, при возникновении конфликтов, замки отдаются потоку, который дольше всего ожидает. В противном случае этот замок не гарантирует какой-либо определённый порядок доступа. Программы, использующие честные замки, доступные многим потокам, могут демонстрировать более низкую общую производительность (то есть, медленнее; часто намного медленнее), чем те, которые используют значение по умолчанию, но имеют меньшие отклонения во времени получения замков и гарантируют отсутствие голодания. Однако обратите внимание, что честность замков не гарантирует честности планирования потоков. Таким образом, один из многих потоков, использующих честный замок, может получить его несколько раз подряд, в то время как другие активные потоки не прогрессируют и не владеют замком в данный момент. Также обратите внимание, что асинхронный метод tryLock() не учитывает установку честности. Он будет успешным, если замок доступен, даже если другие потоки ждут.

Рекомендуется всегда немедленно следовать вызову lock блоком try, чаще всего в структуре типа «до/после»:

class X {
   private final ReentrantLock lock = new ReentrantLock();
   // ...

   public void m() {
     lock.lock();  // block until condition holds
     try {
       // ... method body
     } finally {
       lock.unlock()
     }
   }
 }

Помимо реализации интерфейса Lock, этот класс определяет ряд public и protected методов для проверки состояния замка. Некоторые из этих методов полезны только для инструментирования и мониторинга.

Сериализация этого класса работает так же, как и встроенные замки: десериализованный замок находится в разблокированном состоянии, независимо от его состояния при сериализации.

Этот замок поддерживает максимум 2147483647 рекурсивных блокировок одним и тем же потоком. Попытки превысить этот предел приводят к исключению Error из методов блокировки.

С тех пор:
1.5
См. также:
Сериализованная форма

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

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

Создаёт экземпляр ReentrantLock.

ReentrantLock​(boolean fair)

Создаёт экземпляр ReentrantLock с заданной политикой честности.

Методы

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

Запрашивает количество удержаний этого замка текущим потоком.

protected Thread getOwner()

Возвращает поток, который в настоящее время владеет этим замком, или null если он не владеть.

protected Collection<Thread> getQueuedThreads()

Возвращает коллекцию, содержащую потоки, которые могут ожидать получения этого замка.

int getQueueLength()

Возвращает оценку количества потоков, ожидающих получения этого замка.

protected Collection<Thread> getWaitingThreads​(Condition condition)

Возвращает коллекцию, содержащую те потоки, которые могут ожидать заданного условия, связанного с этим замком.

int getWaitQueueLength​(Condition condition)

Возвращает оценку количества потоков, ожидающих заданного условия, связанного с этим замком.

boolean hasQueuedThread​(Thread thread)

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

boolean hasQueuedThreads()

Запрашивает, ожидают ли какие-либо потоки получения этого замка.

boolean hasWaiters​(Condition condition)

Запрашивает, ожидают ли какие-либо потоки заданного условия, связанного с этим замком.

boolean isFair()

Возвращает true если для этого замка установлена честность.

boolean isHeldByCurrentThread()

Запрашивает, владеет ли этот замок текущий поток.

boolean isLocked()

Запрашивает, владеет ли этот замок какой-либо поток.

void lock()

Получает замок.

void lockInterruptibly()

Получает замок, если текущий поток не был прерван.

Condition newCondition()

Возвращает экземпляр Condition для использования с этим экземпляром Lock.

String toString()

Возвращает строку, идентифицирующую этот замок, а также его состояние.

boolean tryLock()

Получает замок только в том случае, если он не удерживается другим потоком в момент вызова.

boolean tryLock​(long timeout, TimeUnit unit)

Получает замок, если он не удерживается другим потоком в течение заданного времени ожидания, и текущий поток не был прерван.

void unlock()

Попытка освободить этот замок.

Методы, объявленные в классе java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

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

ReentrantLock

public ReentrantLock()

Создаёт экземпляр ReentrantLock. Это эквивалентно использованию ReentrantLock(false).

ReentrantLock

public ReentrantLock(boolean fair)

Создаёт экземпляр ReentrantLock с заданной политикой честности.

Параметры:
fair - true если этот замок должен использовать политику честного упорядочения

Методы

lock

public void lock()

Захватывает блокировку.

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

Если текущая нить уже удерживает блокировку, то счётчик удержания увеличивается на единицу, и метод возвращает значение немедленно.

Если блокировка удерживается другой нитью, то текущая нить отключается для целей планирования потоков и находится в состоянии ожидания, пока блокировка не будет захвачена. В этот момент счётчик удержания блокировки устанавливается в единицу.

Определено в:
lock в интерфейсе Lock

lockInterruptibly

public void lockInterruptibly()
                       throws InterruptedException

Захватывает блокировку, если текущая нить не была прервана.

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

Если текущая нить уже удерживает эту блокировку, то счётчик удержания увеличивается на единицу, и метод возвращает значение немедленно.

Если блокировка удерживается другой нитью, то текущая нить отключается для целей планирования потоков и находится в состоянии ожидания, пока не произойдёт одно из двух:

  • Блокировка захватывается текущей нитью; или
  • Некоторая другая нить прерывает текущую нить.

Если блокировка захвачена текущей нитью, то счётчик удержания блокировки устанавливается в единицу.

Если текущая нить:

  • имеет установленный флаг прерывания при входе в этот метод; или
  • была прервана во время захвата блокировки,
то выбрасывается исключение InterruptedException, и флаг прерывания текущей нити сбрасывается.

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

Определено в:
lockInterruptibly в интерфейсе Lock
Выбрасывает:
InterruptedException - если текущая нить прервана

tryLock

public boolean tryLock()

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

Захватывает блокировку, если она не удерживается другой нитью, и возвращает значение немедленно со значением true, устанавливая счётчик удержания блокировки в единицу. Даже если эта блокировка настроена на использование справедливой политики упорядочения, вызов tryLock() немедленно захватит блокировку, если она доступна, независимо от того, ожидают ли другие нити блокировку. Это поведение «вторжения» может быть полезным в определённых ситуациях, даже несмотря на то, что оно нарушает справедливость. Если вы хотите соблюдать настройки справедливости для этой блокировки, используйте tryLock(0, TimeUnit.SECONDS), который практически эквивалентен (он также обнаруживает прерывание).

Если текущая нить уже удерживает эту блокировку, то счётчик удержания увеличивается на единицу, и метод возвращает true.

Если блокировка удерживается другой нитью, то этот метод вернёт значение немедленно со значением false.

Определено в:
tryLock в интерфейсе Lock
Возвращает:
true если блокировка была свободной и была захвачена текущей нитью, или блокировка уже удерживалась текущей нитью; и false в противном случае

tryLock

public boolean tryLock(long timeout,
                       TimeUnit unit)
                throws InterruptedException

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

Захватывает блокировку, если она не удерживается другой нитью, и возвращает значение немедленно со значением true, устанавливая счётчик удержания блокировки в единицу. Если для этой блокировки установлена справедливая политика упорядочения, то доступная блокировка не будет захвачена, если какие-либо другие нити ожидают блокировку. Это в отличие от метода tryLock(). Если вам нужна блокировка с таймаутом tryLock, которая допускает «вторжение» при справедливой блокировке, то объедините временные и не временные формы вместе:

if (lock.tryLock() ||
     lock.tryLock(timeout, unit)) {
   ...
 }

Если текущая нить уже удерживает эту блокировку, то счётчик удержания увеличивается на единицу, и метод возвращает true.

Если блокировка удерживается другой нитью, то текущая нить отключается для целей планирования потоков и находится в состоянии ожидания, пока не произойдёт одно из трёх:

  • Блокировка захватывается текущей нитью; или
  • Некоторая другая нить прерывает текущую нить; или
  • Заданное время ожидания истекает.

Если блокировка захвачена, то возвращается значение true и счётчик удержания блокировки устанавливается в единицу.

Если текущая нить:

  • имеет установленный флаг прерывания при входе в этот метод; или
  • была прервана во время захвата блокировки,
то выбрасывается исключение InterruptedException, и флаг прерывания текущей нити сбрасывается.

Если заданное время ожидания истекает, то возвращается значение false. Если время меньше или равно нулю, метод вообще не будет ждать.

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

Определено в:
tryLock в интерфейсе Lock
Параметры:
timeout - время ожидания блокировки
unit - единица измерения времени таймаута
Возвращает:
true если блокировка была свободной и была захвачена текущей нитью, или блокировка уже удерживалась текущей нитью; и false если время ожидания истекло, прежде чем блокировка могла быть захвачена
Выбрасывает:
InterruptedException - если текущая нить прервана
NullPointerException - если единица измерения времени равна null

unlock

public void unlock()

Попытка освободить блокировку.

Если текущая нить является держателем этой блокировки, то счётчик удержания уменьшается. Если счётчик удержания теперь равен нулю, то блокировка освобождается. Если текущая нить не является держателем этой блокировки, то выбрасывается исключение IllegalMonitorStateException.

Определено в:
unlock в интерфейсе Lock
Выбрасывает:
IllegalMonitorStateException - если текущая нить не удерживает эту блокировку

newCondition

public Condition newCondition()

Возвращает экземпляр Condition для использования с этим экземпляром Lock.

Возвращённый экземпляр Condition поддерживает те же методы, что и методы монитора Object (wait, notify и notifyAll) при использовании с встроенной блокировкой монитора.

  • Если эта блокировка не удерживается, когда вызываются любые из методов ожидания или сигнализации Condition, то выбрасывается IllegalMonitorStateException.
  • Когда вызываются методы ожидания условия ожидания, блокировка освобождается и, прежде чем они вернут управление, блокировка повторно захватывается, и счётчик удержания блокировки восстанавливается до того значения, которое он имел при вызове метода.
  • Если нить прерывается прерывается во время ожидания, то ожидание завершается, выбрасывается исключение InterruptedException, и флаг прерывания нити сбрасывается.
  • Ожидающие нити сигнализируются в порядке FIFO.
  • Порядок повторного захвата блокировки для нитей, возвращающихся из методов ожидания, такой же, как для нитей, первоначально захвативших блокировку, что по умолчанию не задано, но для справедливых блокировок отдаёт предпочтение тем нитям, которые ожидают дольше всего.
Определено в:
newCondition в интерфейсе Lock
Возвращает:
объект Condition

getHoldCount

public int getHoldCount()

Запрашивает количество удержаний этой блокировки текущей нитью.

У нити есть удержание блокировки для каждого действия захвата блокировки, которое не соответствует действию её освобождения.

Информация о количестве удержаний обычно используется только для тестирования и отладки. Например, если определённый фрагмент кода не должен выполняться при условии, что блокировка уже удерживается, мы можем утверждать этот факт:

class X {
   ReentrantLock lock = new ReentrantLock();
   // ...
   public void m() {
     assert lock.getHoldCount() == 0;
     lock.lock();
     try {
       // ... method body
     } finally {
       lock.unlock();
     }
   }
 }
Возвращает:
количество удержаний этой блокировки текущей нитью или ноль, если эта блокировка не удерживается текущей нитью

isHeldByCurrentThread

public boolean isHeldByCurrentThread()

Запрашивает, удерживается ли эта блокировка текущей нитью.

Аналогично методу Thread.holdsLock(Object) для встроенных блокировок монитора, этот метод обычно используется для отладки и тестирования. Например, метод, который должен вызываться только при условии удержания блокировки, может утверждать, что это так:

class X {
   ReentrantLock lock = new ReentrantLock();
   // ...

   public void m() {
       assert lock.isHeldByCurrentThread();
       // ... method body
   }
 }

Он также может использоваться для обеспечения того, что рекурсивный замок используется нерекурсивным способом, например:

class X {
   ReentrantLock lock = new ReentrantLock();
   // ...

   public void m() {
       assert !lock.isHeldByCurrentThread();
       lock.lock();
       try {
           // ... method body
       } finally {
           lock.unlock();
       }
   }
 }
Возвращает:
true если текущая нить удерживает эту блокировку, и false в противном случае

isLocked

public boolean isLocked()

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

Возвращает:
true если какая-либо нить удерживает эту блокировку, и false в противном случае

isFair

public final boolean isFair()

Возвращает true если для этой блокировки установлено значение справедливости true.

Возвращает:
true если для этой блокировки установлено значение справедливости true

getOwner

protected Thread getOwner()

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

Возвращает:
владелец или null если им не владеет

hasQueuedThreads

public final boolean hasQueuedThreads()

Определяет, ожидают ли какие-либо потоки получения этого замка. Обратите внимание, что из-за возможных отмен в любое время, возвращаемое значение true не гарантирует, что любой другой поток когда-либо получит этот замок. Этот метод предназначен в основном для мониторинга состояния системы.

Возвращает:
true если могут быть другие ожидающие потоки для получения замка

hasQueuedThread

public final boolean hasQueuedThread(Thread thread)

Определяет, ожидает ли данный поток получения этого замка. Обратите внимание, что из-за возможных отмен в любое время, возвращаемое значение true не гарантирует, что этот поток когда-либо получит этот замок. Этот метод предназначен в основном для мониторинга состояния системы.

Параметры:
thread - поток
Возвращает:
true если заданный поток стоит в очереди, ожидая этого замка
Исключения:
NullPointerException - если поток равен null

getQueueLength

public final int getQueueLength()

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

Возвращает:
оценочное количество потоков, ожидающих этого замка

getQueuedThreads

protected Collection<Thread> getQueuedThreads()

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

Возвращает:
коллекция потоков

hasWaiters

public boolean hasWaiters(Condition condition)

Определяет, ожидают ли какие-либо потоки на заданном условии, связанном с этим замком. Обратите внимание, что из-за таймаутов и прерываний в любое время, возвращаемое значение true не гарантирует, что будущий signal разбудит какие-либо потоки. Этот метод предназначен в основном для мониторинга состояния системы.

Параметры:
condition - условие
Возвращает:
true если есть ожидающие потоки
Исключения:
IllegalMonitorStateException - если этот замок не удерживается
IllegalArgumentException - если заданное условие не ассоциировано с этим замком
NullPointerException - если условие равно null

getWaitQueueLength

public int getWaitQueueLength(Condition condition)

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

Параметры:
condition - условие
Возвращает:
оценочное количество ожидающих потоков
Исключения:
IllegalMonitorStateException - если этот замок не удерживается
IllegalArgumentException - если заданное условие не ассоциировано с этим замком
NullPointerException - если условие равно null

getWaitingThreads

protected Collection<Thread> getWaitingThreads(Condition condition)

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

Параметры:
condition - условие
Возвращает:
коллекция потоков
Исключения:
IllegalMonitorStateException - если этот замок не удерживается
IllegalArgumentException - если заданное условие не ассоциировано с этим замком
NullPointerException - если условие равно null

toString

public String toString()

Возвращает строку, идентифицирующую этот замок, а также его состояние. Состояние в скобках включает либо строку "Unlocked", либо строку "Locked by" за которой следует имя владеющего потока.

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

© 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/ReentrantLock.html

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