Класс LockSupport
- java.lang.Object
-
- java.util.concurrent.locks.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(Thread t) | Возвращает объект блокировщика, предоставленный последним вызовом метода парковки, который ещё не разблокирован, или null, если не заблокирован. |
static void | park() | Отключает текущий поток для целей планирования потоков, если разрешение недоступно. |
static void | park(Object blocker) | Отключает текущий поток для целей планирования потоков, если разрешение недоступно. |
static void | parkNanos(long nanos) | Отключает текущий поток для целей планирования потоков на заданное время ожидания, если разрешение недоступно. |
static void | parkNanos(Object blocker,
long nanos) | Отключает текущий поток для целей планирования потоков на заданное время ожидания, если разрешение недоступно. |
static void | parkUntil(long deadline) | Отключает текущий поток для целей планирования потоков до указанного крайнего срока, если разрешение недоступно. |
static void | parkUntil(Object blocker,
long deadline) | Отключает текущий поток для целей планирования потоков до указанного крайнего срока, если разрешение недоступно. |
static void | unpark(Thread thread) | Делает разрешение доступным для данного потока, если оно ещё не было доступно. |
Методы, объявленные в классе java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait Методы
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)
Возвращает объект блокировки, предоставленный последним вызовом метода park, который ещё не разблокирован, или null, если не заблокирован. Возвращаемое значение — лишь мгновенный снимок — поток может с тех пор быть разблокирован или заблокирован на другом объекте блокировки.
- Параметры:
-
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, 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.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/locks/LockSupport.html