Spec-Zone.ru › OpenJDK 8

Класс ReentrantLock

  • java.lang.Object
    • java.util.concurrent.locks.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 выбрасываемым из методов блокировки.

Since:
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 если для этого мьютекса установлена честность

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.

Spec-Zone.ru

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