Класс LockSupport
public final class LockSupport extends Object
Этот класс связывает с каждым использующим его потоком разрешение (в смысле класса Semaphore). Вызов park немедленно возвращает управление, если разрешение доступно, при этом оно расходуется; в противном случае поток может быть заблокирован. Вызов unpark делает разрешение доступным, если оно ещё не было доступно. (Однако, в отличие от семафоров, разрешения не накапливаются. Их может быть не более одного.) Для надёжного использования требуются volatile-переменные (или атомарные переменные), чтобы управлять тем, когда поток должен быть припаркован или разблокирован. Порядок вызовов этих методов сохраняется относительно обращений к volatile-переменным, но не обязательно относительно обращений к обычным переменным.
Методы park и unpark позволяют эффективно блокировать и разблокировать потоки, не сталкиваясь с проблемами, из-за которых устаревшие методы Thread.suspend и Thread.resume непригодны для таких целей: гонки между вызовом park одним потоком и попыткой другого потока выполнить unpark сохраняют возможность продвижения благодаря разрешению. Кроме того, park вернёт управление, если поток вызывающего кода был прерван; также поддерживаются варианты с тайм-аутом. Метод park может вернуться и в любое другое время, «без причины», поэтому обычно его нужно вызывать в цикле, который при возврате повторно проверяет условия. В этом смысле park служит оптимизацией «активного ожидания»: он сокращает бесполезное вращение в цикле, но для эффективности его необходимо сочетать с unpark.
Все три варианта park также поддерживают параметр-объект blocker. Этот объект сохраняется на время блокировки потока, позволяя средствам мониторинга и диагностики определять причины блокировки потоков. (Такие средства могут получить блокирующий объект с помощью метода getBlocker(Thread).) Настоятельно рекомендуется использовать эти варианты вместо исходных вариантов без этого параметра. Обычно в качестве blocker в реализации блокировки следует передавать this.
Эти методы предназначены для использования в качестве инструментов создания высокоуровневых средств синхронизации и сами по себе не подходят для большинства задач управления параллельным выполнением. Метод park предназначен для использования только в конструкциях следующего вида:
while (!canProceed()) {
// ensure request to unpark is visible to other threads
...
LockSupport.park(this);
} где никакие действия потока, публикующего запрос на разблокировку, до вызова park, не связаны с блокировкой или ожиданием. Поскольку с каждым потоком связано только одно разрешение, любые промежуточные вызовы park, в том числе неявные, например при загрузке класса, могут привести к зависанию потока («потерянной разблокировке»). Пример использования. Ниже приведён набросок реализации нерекурсивной блокировки с очередью FIFO:
class FIFOMutex {
private final AtomicBoolean locked = new AtomicBoolean(false);
private final Queue<Thread> waiters
= new ConcurrentLinkedQueue<>();
public void lock() {
boolean wasInterrupted = false;
// publish current thread for unparkers
waiters.add(Thread.currentThread());
// Block while not first in queue or cannot acquire lock
while (waiters.peek() != Thread.currentThread() ||
!locked.compareAndSet(false, true)) {
LockSupport.park(this);
// ignore interrupts while waiting
if (Thread.interrupted())
wasInterrupted = true;
}
waiters.remove();
// ensure correct interrupted status on return
if (wasInterrupted)
Thread.currentThread().interrupt();
}
public void unlock() {
locked.set(false);
LockSupport.unpark(waiters.peek());
}
static {
// Reduce the risk of "lost unpark" due to classloading
Class<?> ensureLoaded = LockSupport.class;
}
}
- Начиная с:
- 1.5
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
static Object |
getBlocker |
Возвращает объект-блокировщик, переданный при последнем вызове метода park, который ещё не разблокировал поток, или null, если поток не заблокирован. |
static void |
park() |
Отключает текущий поток от планирования, если разрешение недоступно. |
static void |
park |
Отключает текущий поток от планирования, если разрешение недоступно. |
static void |
parkNanos |
Отключает текущий поток от планирования на указанный период ожидания, если разрешение недоступно. |
static void |
parkNanos |
Отключает текущий поток от планирования на указанный период ожидания, если разрешение недоступно. |
static void |
parkUntil |
Отключает текущий поток от планирования до указанного срока, если разрешение недоступно. |
static void |
parkUntil |
Отключает текущий поток от планирования до указанного срока, если разрешение недоступно. |
static void |
setCurrentBlocker |
Задаёт объект, который будет возвращаться при вызове getBlocker для текущего потока. |
static void |
unpark |
Делает разрешение доступным для указанного потока, если оно ещё не было доступно. |
Методы, объявленные в классе Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait | Модификатор и тип | Метод | Описание |
|---|---|---|
protected Object |
clone() |
Создаёт и возвращает копию этого объекта. |
boolean |
equals |
Определяет, «равен ли» этот объект другому объекту. |
protected void |
finalize() |
Устарело, подлежит удалению: этот элемент API может быть удалён в будущей версии. Финализация объявлена устаревшей и подлежит удалению в одном из будущих выпусков. |
final Class |
getClass() |
Возвращает класс времени выполнения этого Object. |
int |
hashCode() |
Возвращает хеш-код этого объекта. |
final void |
notify() |
Пробуждает один поток, ожидающий на мониторе этого объекта. |
final void |
notifyAll() |
Пробуждает все потоки, ожидающие на мониторе этого объекта. |
String |
toString() |
Возвращает строковое представление объекта. |
final void |
wait() |
Заставляет текущий поток ожидать пробуждения, обычно посредством уведомления или прерывания. |
final void |
wait |
Заставляет текущий поток ожидать пробуждения, обычно посредством уведомления или прерывания, либо до истечения заданного промежутка реального времени. |
final void |
wait |
Заставляет текущий поток ожидать пробуждения, обычно посредством уведомления или прерывания, либо до истечения заданного промежутка реального времени. |
Подробное описание методов
setCurrentBlocker
public static void setCurrentBlocker(Object blocker)
getBlocker для текущего потока. Этот метод можно использовать перед вызовом версии park() без аргументов из непубличных объектов, чтобы упростить диагностику или сохранить совместимость с предыдущими реализациями методов блокировки. Предыдущие значения блокирующего объекта не восстанавливаются автоматически после блокировки. Чтобы добиться эффекта park(b}, используйте
setCurrentBlocker(b); park(); setCurrentBlocker(null);
- Параметры:
-
blocker— объект-блокировщик - Начиная с:
- 14
unpark
public static void unpark(Thread thread)
park, он будет разблокирован. В противном случае гарантируется, что следующий вызов им park не приведёт к блокировке. Эта операция не гарантирует какого-либо эффекта, если указанный поток не был запущен.- Параметры:
-
thread— поток, который нужно разблокировать, илиnull, в этом случае операция не оказывает эффекта
park
public static void park(Object blocker)
Если разрешение доступно, оно расходуется, и вызов немедленно возвращает управление; в противном случае текущий поток отключается от планирования и остаётся в ожидании до наступления одного из трёх событий:
- Другой поток вызывает
unpark, указывая текущий поток в качестве целевого; или - Другой поток вызывает прерывание текущего потока; или
- Вызов неожиданно возвращает управление (то есть без причины).
Этот метод не сообщает, какое из этих событий вызвало возврат. Вызывающий код должен повторно проверить условия, из-за которых поток был припаркован. Например, вызывающий код также может проверить состояние прерывания потока после возврата.
- Параметры:
-
blocker— объект синхронизации, из-за которого этот поток был припаркован - Начиная с:
- 1.6
parkNanos
public static void parkNanos(Object blocker, long nanos)
Если указанный период ожидания равен нулю или меньше нуля, метод ничего не делает. В противном случае, если разрешение доступно, оно расходуется, и вызов немедленно возвращает управление; иначе текущий поток отключается от планирования и остаётся в ожидании до наступления одного из четырёх событий:
- Другой поток вызывает
unpark, указывая текущий поток в качестве целевого; или - Другой поток вызывает прерывание текущего потока; или
- Истекает указанный период ожидания; или
- Вызов неожиданно возвращает управление (то есть без причины).
Этот метод не сообщает, какое из этих событий вызвало возврат. Вызывающий код должен повторно проверить условия, из-за которых поток был припаркован. Например, вызывающий код также может проверить состояние прерывания потока или прошедшее время после возврата.
- Параметры:
-
blocker— объект синхронизации, из-за которого этот поток был припаркован -
nanos— максимальное время ожидания в наносекундах - Начиная с:
- 1.6
parkUntil
public static void parkUntil(Object blocker, long deadline)
Если разрешение доступно, оно расходуется, и вызов немедленно возвращает управление; в противном случае текущий поток отключается от планирования и остаётся в ожидании до наступления одного из четырёх событий:
- Другой поток вызывает
unpark, указывая текущий поток в качестве целевого; или - Другой поток вызывает прерывание текущего потока; или
- Наступает указанный срок; или
- Вызов неожиданно возвращает управление (то есть без причины).
Этот метод не сообщает, какое из этих событий вызвало возврат. Вызывающий код должен повторно проверить условия, из-за которых поток был припаркован. Например, вызывающий код также может проверить состояние прерывания потока или текущее время после возврата.
- Параметры:
-
blocker— объект синхронизации, из-за которого этот поток был припаркован -
deadline— абсолютное время в миллисекундах от начала эпохи, до которого нужно ожидать - Начиная с:
- 1.6
getBlocker
public static Object getBlocker(Thread t)
- Параметры:
-
t— поток - Возвращает:
- объект-блокировщик
- Выбрасывает:
-
NullPointerException— если аргумент равен null - Начиная с:
- 1.6
park
public static void park()
Если разрешение доступно, оно расходуется, и вызов немедленно возвращает управление; в противном случае текущий поток отключается от планирования и остаётся в ожидании до наступления одного из трёх событий:
- Другой поток вызывает
unpark, указывая текущий поток в качестве целевого; или - Другой поток вызывает прерывание текущего потока; или
- Вызов неожиданно возвращает управление (то есть без причины).
Этот метод не сообщает, какое из этих событий вызвало возврат. Вызывающий код должен повторно проверить условия, из-за которых поток был припаркован. Например, вызывающий код также может проверить состояние прерывания потока после возврата.
parkNanos
public static void parkNanos(long nanos)
Если указанный период ожидания равен нулю или меньше нуля, метод ничего не делает. В противном случае, если разрешение доступно, оно расходуется, и вызов немедленно возвращает управление; иначе текущий поток отключается от планирования и остаётся в ожидании до наступления одного из четырёх событий:
- Другой поток вызывает
unpark, указывая текущий поток в качестве целевого; или - Другой поток вызывает прерывание текущего потока; или
- Истекает указанный период ожидания; или
- Вызов неожиданно возвращает управление (то есть без причины).
Этот метод не сообщает, какое из этих событий вызвало возврат. Вызывающий код должен повторно проверить условия, из-за которых поток был припаркован. Например, вызывающий код также может проверить состояние прерывания потока или прошедшее время после возврата.
- Параметры:
-
nanos— максимальное время ожидания в наносекундах
parkUntil
public static void parkUntil(long deadline)
Если разрешение доступно, оно расходуется, и вызов немедленно возвращает управление; в противном случае текущий поток отключается от планирования и остаётся в ожидании до наступления одного из четырёх событий:
- Другой поток вызывает
unpark, указывая текущий поток в качестве целевого; или - Другой поток вызывает прерывание текущего потока; или
- Наступает указанный срок; или
- Вызов неожиданно возвращает управление (то есть без причины).
Этот метод не сообщает, какое из этих событий вызвало возврат. Вызывающий код должен повторно проверить условия, из-за которых поток был припаркован. Например, вызывающий код также может проверить состояние прерывания потока или текущее время после возврата.
- Параметры:
-
deadline— абсолютное время в миллисекундах от начала эпохи, до которого нужно ожидать
© 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.