- java.lang.Object
-
- java.util.concurrent.locks.LockSupport
-
public class LockSupport extends Object
用于创建锁和其他同步类的基本线程阻塞原语。该类与使用它的每个线程关联一个许可证(在
Semaphore
类的意义上)。 如果许可证可用,将立即返回park
,并在此过程中消费; 否则可能会阻止。 如果尚未提供许可,则致电unpark
获得许可。 (与Semaphores不同,许可证不会累积。最多只有一个。)可靠的使用需要使用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
需要锁定或阻塞。 因为每个线程只有一个许可证,所以任何中间使用park
,包括隐式地通过类加载,都可能导致无响应的线程(“丢失unpark”)。样品使用。 以下是先进先出非重入锁定类的草图:
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)
返回提供给尚未解除阻塞的park方法的最新调用的阻止程序对象,如果未阻止,则返回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)
如果给定线程尚不可用,则为其提供许可。
-
-
-
方法详细信息
-
unpark
public static void unpark(Thread thread)
如果给定线程尚不可用,则为其提供许可。 如果该线程在park
上被阻止,则它将解除阻止。 否则,它的下一次调用park
保证不会阻止。 如果尚未启动给定线程,则不保证此操作完全没有任何效果。- 参数
-
thread
-thread
的线程,或null
,在这种情况下此操作无效
-
park
public static void park(Object blocker)
除非许可证可用,否则禁用当前线程以进行线程调度。如果许可证可用,那么它被消耗并且呼叫立即返回; 否则当前线程因线程调度而被禁用,并且在发生以下三种情况之一之前处于休眠状态:
- 其他一些线程以当前线程作为目标调用
unpark
; 要么 - 其他一些线程interrupts当前线程; 要么
- 虚假的呼叫(即无缘无故)返回。
这种方法不报告是哪个线程导致该方法返回。 呼叫者应该首先重新检查导致线程停放的条件。 例如,呼叫者还可以确定返回时线程的中断状态。
- 参数
-
blocker
- 负责此线程停放的同步对象 - 从以下版本开始:
- 1.6
- 其他一些线程以当前线程作为目标调用
-
parkNanos
public static void parkNanos(Object blocker, long nanos)
除非许可证可用,否则禁用当前线程以进行线程调度,直到指定的等待时间。如果许可证可用,那么它被消耗并且呼叫立即返回; 否则当前线程因线程调度而被禁用,并且在发生以下四种情况之一之前处于休眠状态:
- 其他一些线程调用
unpark
,当前线程作为目标; 要么 - 其他一些线程interrupts当前线程; 要么
- 指定的等待时间过去了; 要么
- 虚假的呼叫(即无缘无故)返回。
这种方法不报告是哪个线程导致该方法返回。 呼叫者应该首先重新检查导致线程停放的条件。 例如,呼叫者还可以确定线程的中断状态或返回时经过的时间。
- 参数
-
blocker
- 负责此线程停放的同步对象 -
nanos
- 等待的最大纳秒数 - 从以下版本开始:
- 1.6
- 其他一些线程调用
-
parkUntil
public static void parkUntil(Object blocker, long deadline)
除非许可证可用,否则禁用当前线程以进行线程调度,直到指定的截止时间。如果许可证可用,那么它被消耗并且呼叫立即返回; 否则当前线程因线程调度而被禁用,并且在发生以下四种情况之一之前处于休眠状态:
- 其他一些线程调用
unpark
,当前线程作为目标; 要么 - 其他一些线程interrupts当前线程; 要么
- 指定的截止日期过去了; 要么
- 虚假的呼叫(即无缘无故)返回。
这种方法不报告是哪个线程导致该方法返回。 呼叫者应该首先重新检查导致线程停放的条件。 例如,呼叫者还可以确定线程的中断状态或返回时的当前时间。
- 参数
-
blocker
- 负责此线程停放的同步对象 -
deadline
- 从纪元开始,以毫秒为单位的绝对时间 - 从以下版本开始:
- 1.6
- 其他一些线程调用
-
getBlocker
public static Object getBlocker(Thread t)
返回提供给尚未解除阻塞的park方法的最新调用的阻止程序对象,如果未阻止,则返回null。 返回的值只是一个瞬间快照 - 该线程可能已经在不同的阻止对象上解除阻塞或阻塞。- 参数
-
t
- 线程 - 结果
- 阻挡者
- 异常
-
NullPointerException
- 如果参数为null - 从以下版本开始:
- 1.6
-
park
public static void park()
除非许可证可用,否则禁用当前线程以进行线程调度。如果许可证可用,那么它被消耗并且呼叫立即返回; 否则当前线程因线程调度而被禁用,并且在发生以下三种情况之一之前处于休眠状态:
- 其他一些线程调用
unpark
,当前线程作为目标; 要么 - 其他一些线程interrupts当前线程; 要么
- 虚假的呼叫(即无缘无故)返回。
这种方法不报告是哪个线程导致该方法返回。 呼叫者应该首先重新检查导致线程停放的条件。 例如,呼叫者还可以确定返回时线程的中断状态。
- 其他一些线程调用
-
parkNanos
public static void parkNanos(long nanos)
除非许可证可用,否则禁用当前线程以进行线程调度,直到指定的等待时间。如果许可证可用,那么它被消耗并且呼叫立即返回; 否则当前线程因线程调度而被禁用,并且在发生以下四种情况之一之前处于休眠状态:
- 其他一些线程以当前线程作为目标调用
unpark
; 要么 - 其他一些线程interrupts当前线程; 要么
- 指定的等待时间过去了; 要么
- 虚假的呼叫(即无缘无故)返回。
这种方法不报告是哪个线程导致该方法返回。 呼叫者应该首先重新检查导致线程停放的条件。 例如,呼叫者还可以确定线程的中断状态或返回时经过的时间。
- 参数
-
nanos
- 等待的最大纳秒数
- 其他一些线程以当前线程作为目标调用
-
parkUntil
public static void parkUntil(long deadline)
除非许可证可用,否则禁用当前线程以进行线程调度,直到指定的截止时间。如果许可证可用,那么它被消耗并且呼叫立即返回; 否则当前线程因线程调度而被禁用,并且在发生以下四种情况之一之前处于休眠状态:
- 其他一些线程调用
unpark
,当前线程作为目标; 要么 - 其他一些线程interrupts当前线程; 要么
- 指定的截止日期过去了; 要么
- 虚假的呼叫(即无缘无故)返回。
这种方法不报告是哪个线程导致该方法返回。 呼叫者应该首先重新检查导致线程停放的条件。 例如,呼叫者还可以确定线程的中断状态或返回时的当前时间。
- 参数
-
deadline
- 从纪元开始,以毫秒为单位的绝对时间
- 其他一些线程调用
-
-