Spec-Zone.ru › OpenJDK 25

Класс 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 и всегда сразу вызывать unlock в качестве первого оператора блока finally, как показано ниже:

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

  public void m() {
    lock.lock();  // lock() as the last statement before the try block
    try {
      // ... method body
    } finally {
      lock.unlock(); // unlock() as the first statement in the finally block
    }
  }
}

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

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

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

Начиная с версии:
1.5
См. также:
  • Форма сериализации

Краткое описание конструкторов

Конструктор Описание
ReentrantLock()
Создаёт экземпляр ReentrantLock.
ReentrantLock(boolean fair)
Создаёт экземпляр ReentrantLock с указанной политикой справедливости.

Краткое описание методов

Модификатор и тип Метод Описание
int getHoldCount()
Возвращает количество захватов этой блокировки текущим потоком.
protected Thread getOwner()
Возвращает поток, которому в данный момент принадлежит эта блокировка, или null, если она никому не принадлежит.
protected Collection<Thread> getQueuedThreads()
Возвращает коллекцию потоков, которые могут ожидать захвата этой блокировки.
final int getQueueLength()
Возвращает оценочное количество потоков, ожидающих захвата этой блокировки.
protected Collection<Thread> getWaitingThreads(Condition condition)
Возвращает коллекцию потоков, которые могут ожидать указанного условия, связанного с этой блокировкой.
int getWaitQueueLength(Condition condition)
Возвращает оценочное количество потоков, ожидающих указанного условия, связанного с этой блокировкой.
final boolean hasQueuedThread(Thread thread)
Проверяет, ожидает ли указанный поток захвата этой блокировки.
final boolean hasQueuedThreads()
Проверяет, ожидают ли какие-либо потоки захвата этой блокировки.
boolean hasWaiters(Condition condition)
Проверяет, ожидают ли какие-либо потоки указанного условия, связанного с этой блокировкой.
final 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()
Пытается освободить эту блокировку.

Методы, объявленные в классе 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 {
  final 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 {
  final ReentrantLock lock = new ReentrantLock();
  // ...

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

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

class X {
  final 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
Возвращает:
строку, идентифицирующую эту блокировку и описывающую её состояние

Сообщить об ошибке или предложить улучшение
Дополнительную справочную информацию по API и документацию для разработчиков см. в разделе Документация Java SE, содержащем более подробные описания для разработчиков, обзоры концепций, определения терминов, способы обхода проблем и примеры работающего кода. Другие версии.
Java является товарным знаком или зарегистрированным товарным знаком Oracle и/или её аффилированных лиц в США и других странах.
Авторские права © 1993, 2025, Oracle и/или её аффилированные лица, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
Все права защищены. Использование регулируется условиями лицензии и политикой распространения документации.

© 1993, 2025, 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/25/docs/api/java.base/java/util/concurrent/locks/ReentrantLock.html

Spec-Zone.ru

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