Класс LockSupport
public class LockSupport extends Object
Этот класс связывает с каждым потоком, который его использует, разрешение (в смысле класса Semaphore). Вызов park вернёт результат немедленно, если разрешение доступно, потребляя его в процессе; в противном случае может произойти блокировка. Вызов unpark делает разрешение доступным, если оно ещё не было доступно. (В отличие от семафоров, разрешения не накапливаются. Их может быть не более одного.) Надёжное использование требует использования переменных volatile (или атомных) для управления временем ожидания или разблокировки. Порядок вызовов этих методов поддерживается относительно доступа к переменным 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 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 |
Возвращает объект блокировки, предоставленный последнему вызову метода 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 |
Делает доступным разрешение для данного потока, если оно ещё не было доступно. |
Подробное описание методов
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://download.java.net/java/early_access/jdk24/docs/api/java.base/java/util/concurrent/locks/LockSupport.html