Класс 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, в том числе неявное при загрузке класса, может привести к тому, что поток перестанет реагировать («потерянное возобновление»). Пример использования. Ниже приведён эскиз класса нерекурсивной блокировки с дисциплиной «первым пришёл — первым обслужен»:
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 interrupt 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 |
Возвращает объект блокировки, переданный при последнем вызове метода приостановки, который ещё не разблокировал поток, или 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 |
Делает разрешение доступным для указанного потока, если оно ещё не было доступно. |
Подробное описание методов
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.
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/concurrent/locks/LockSupport.html