public class LockSupport extends Object
这个类与每个使用它的线程相关联,一个许可证(在Semaphore
类的意义上)。 如果许可证可用,则呼叫park
将park
返回,在此过程中消耗它; 否则可能会阻止。 致电unpark
使许可证可用,如果尚不可用。 (与信号量不同,许可证不能累积,最多只有一个。)
方法park
和unpark
提供了阻止和解除阻塞线程的有效手段,该方法不会遇到导致不推荐使用的方法Thread.suspend
和Thread.resume
目的不能使用的问题:一个线程调用park
和另一个线程之间的尝试unpark
线程将保持活跃性,由于许可证。 另外,如果调用者的线程被中断, park
将返回,并且支持超时版本。 park
方法也可以在任何其他时间返回,因为“无理由”,因此一般必须在返回之前重新检查条件的循环中被调用。 在这个意义上, park
作为一个“忙碌等待”的优化,不浪费时间旋转,但必须与unpark
配对才能有效。
park
的三种形式也支持blocker
对象参数。 线程被阻止时记录此对象,以允许监视和诊断工具识别线程被阻止的原因。 (此类工具可以使用方法getBlocker(Thread)
访问阻止程序 。)强烈鼓励使用这些形式而不是没有此参数的原始形式。 在锁实现中作为blocker
提供的正常参数是this
。
这些方法被设计为用作创建更高级同步实用程序的工具,并且本身对于大多数并发控制应用程序本身并不有用。 park
方法仅用于形式的构造:
while (!canProceed()) { ... LockSupport.park(this); }
其中既不canProceed
也没有任何其他动作之前的呼叫park
需要锁定或阻止。
因为只有一个许可证与每个线程相关联, park
任何中介使用可能会干扰其预期效果。
样品用法。 这是一个先入先出的非可重入锁类的草图:
class FIFOMutex { private final AtomicBoolean locked = new AtomicBoolean(false); private final Queue<Thread> waiters = new ConcurrentLinkedQueue<Thread>(); public void lock() { boolean wasInterrupted = false; Thread current = Thread.currentThread(); waiters.add(current); // Block while not first in queue or cannot acquire lock while (waiters.peek() != current || !locked.compareAndSet(false, true)) { LockSupport.park(this); if (Thread.interrupted()) // ignore interrupts while waiting wasInterrupted = true; } waiters.remove(); if (wasInterrupted) // reassert interrupt status on exit current.interrupt(); } public void unlock() { locked.set(false); LockSupport.unpark(waiters.peek()); } }
Modifier and Type | Method and Description |
---|---|
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)
为给定的线程提供许可证(如果尚未提供)。
|
public static void unpark(Thread thread)
park
被阻塞,那么它将被解除阻塞。
否则,其下一次拨打park
保证不被阻止。
如果给定的线程尚未启动,则此操作无法保证完全没有任何影响。
thread
- 要取消
thread
的线程,或
null
,在这种情况下,此操作无效
public static void park(Object blocker)
如果许可证可用,则它被消耗,并且该呼叫立即返回; 否则当前线程对于线程调度目的将被禁用,并且处于休眠状态,直至发生三件事情之一:
unpark
; 要么 这种方法不报告是哪个线程导致该方法返回。 来电者应重新检查导致线程首先停放的条件。 呼叫者还可以确定线程在返回时的中断状态。
blocker
- 同步对象负责此线程停车
public static void parkNanos(Object blocker, long nanos)
如果许可证可用,则它被消耗,并且该呼叫立即返回; 否则当前线程对于线程调度目的将被禁用,并且处于休眠状态,直到发生四件事情之一:
unpark
; 要么 这种方法不报告是哪个线程导致该方法返回。 来电者应重新检查导致线程首先停放的条件。 呼叫者还可以确定线程的中断状态,或者返回时经过的时间。
blocker
- 同步对象负责此线程停车
nanos
- 要等待的最大纳秒数
public static void parkUntil(Object blocker, long deadline)
如果许可证可用,则它被消耗,并且该呼叫立即返回; 否则当前线程对于线程调度目的将被禁用,并且处于休眠状态,直到发生四件事情之一:
unpark
; 要么 这种方法不报告是哪个线程导致该方法返回。 来电者应重新检查导致线程首先停放的条件。 呼叫者还可以确定线程的中断状态,或返回当前的时间。
blocker
- 负责此线程停车的同步对象
deadline
- 绝对时间,以毫秒为单位,从时代到等到
public static Object getBlocker(Thread t)
t
- 线程
NullPointerException
- 如果参数为空
public static void park()
如果许可证可用,则它被消耗,并且该呼叫立即返回; 否则当前线程对于线程调度目的将被禁用,并且处于休眠状态,直至发生三件事情之一:
unpark
; 要么 这种方法不报告是哪个线程导致该方法返回。 来电者应重新检查导致线程首先停放的条件。 呼叫者还可以确定线程在返回时的中断状态。
public static void parkNanos(long nanos)
如果许可证可用,则它被消耗,并且该呼叫立即返回; 否则当前线程对于线程调度目的将被禁用,并且处于休眠状态,直到发生四件事情之一:
unpark
; 要么 这种方法不报告是哪个线程导致该方法返回。 来电者应重新检查导致线程首先停放的条件。 呼叫者还可以确定线程的中断状态,或者返回时经过的时间。
nanos
- 等待的最大纳秒数
public static void parkUntil(long deadline)
如果许可证可用,则它被消耗,并且该呼叫立即返回; 否则当前线程对于线程调度目的将被禁用,并且处于休眠状态,直到发生四件事情之一:
unpark
; 要么 这种方法不报告是哪个线程导致该方法返回。 来电者应重新检查导致线程首先停放的条件。 呼叫者还可以确定线程的中断状态,或返回当前的时间。
deadline
- 绝对时间,以毫秒为单位,从时代到等到