public class LockSupport
extends Object
| java.lang.Object | |
| java.util.concurrent.locks.LockSupport | |
用于创建锁定和其他同步类的基本线程阻塞原语。
这个班级与每个使用它的线程关联一个许可证(在Semaphore班的意义上)。 如果许可证可用,呼叫park将立即返回,在此过程中将其消耗; 否则可能会阻塞。 拨打unpark的电话会使许可证可用,如果它尚不可用。 (但与信号量不同,许可不会累积,最多只有一个)。可靠的使用要求使用易失性(或原子)变量来控制何时停放或取消停放。 对这些方法的调用顺序是针对易失性变量访问进行维护的,但不一定是非易失性变量访问。
方法park和unpark提供了有效的阻止和解除阻塞线程的方法,这些线程不会遇到导致不推荐使用的方法Thread.suspend和Thread.resume对于此类用途不可用的问题:调用park一个线程与尝试调用park另一个线程之间的unpark将保持活跃性,由于许可证。 此外,如果调用者线程中断,并且支持超时版本,则将返回park 。 park方法也可以在任何其他时间返回,因为“无理由”,因此通常必须在返回时重新检查条件的循环中调用。 从这个意义上说, park可以作为“忙碌的等待”的优化,不会浪费太多的时间,但必须与unpark配对才能生效。
这三种形式的park每个都支持blocker对象参数。 该对象在线程被阻止时被记录,以允许监视和诊断工具识别线程被阻塞的原因。 (这些工具可能使用方法getBlocker(Thread)访问getBlocker(Thread) 。)强烈建议使用这些表单而不是没有此参数的原始表单。 在锁定实现中作为blocker提供的正常参数是this 。
这些方法旨在用作创建更高级别的同步实用程序的工具,并且本身并不适用于大多数并发控制应用程序。 park方法仅用于表单的构造中:
while (!canProceed()) {
// ensure request to unpark is visible to other threads
...
LockSupport.park(this);
} where no actions by the thread publishing a request to unpark, prior to the call to
park, entail locking or blocking. Because only one permit is associated with each thread, any intermediary uses of
park, including implicitly via class loading, could lead to an unresponsive thread (a "lost 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;
}
}
公共方法(Public methods) |
|
|---|---|
static Object |
getBlocker(Thread t) 返回提供给尚未解锁的park方法的最近调用的阻止器对象,如果未阻止,则返回null。 |
static void |
park() 除非许可证可用,否则为线程调度目的禁用当前线程。 |
static void |
park(Object blocker) 除非许可证可用,否则为线程调度目的禁用当前线程。 |
static void |
parkNanos(Object blocker, long nanos) 除非许可证可用,否则为了线程调度目的禁用当前线程,直到指定的等待时间。 |
static void |
parkNanos(long nanos) 除非许可证可用,否则为了线程调度目的禁用当前线程,直到指定的等待时间。 |
static void |
parkUntil(Object blocker, long deadline) 禁用当前线程以进行线程调度,直到指定的截止日期,除非许可证可用。 |
static void |
parkUntil(long deadline) 禁用当前线程以进行线程调度,直到指定的截止日期,除非许可证可用。 |
static void |
unpark(Thread thread) 如果该线程尚不可用,则为该线程提供许可证。 |
继承方法(Inherited methods) |
|
|---|---|
java.lang.Object
|
|
Object getBlocker (Thread t)
返回提供给尚未解锁的park方法的最近调用的阻止器对象,如果未阻止,则返回null。 返回的值只是一个瞬间快照 - 该线程可能已解锁或阻塞在不同的阻塞器对象上。
| 参数(Parameters) | |
|---|---|
t |
Thread: the thread |
| 返回(Returns) | |
|---|---|
Object |
the blocker |
| 抛出异常(Throws) | |
|---|---|
NullPointerException |
if argument is null |
void park ()
除非许可证可用,否则为线程调度目的禁用当前线程。
如果许可证可用,则它被消耗并且呼叫立即返回; 否则当前线程因为线程调度目的而被禁用,并且处于休眠状态,直到发生以下三件事之一:
unpark with the current thread as the target; or 这种方法不报告是哪个线程导致该方法返回。 来电者应重新检查导致线头停放的条件。 例如,调用者也可以确定线程在返回时的中断状态。
void park (Object blocker)
除非许可证可用,否则为线程调度目的禁用当前线程。
如果许可证可用,则它被消耗并且呼叫立即返回; 否则当前线程因为线程调度目的而被禁用,并且处于休眠状态,直到发生以下三件事之一:
unpark with the current thread as the target; or 这种方法不报告是哪个线程导致该方法返回。 来电者应重新检查导致线头停放的条件。 例如,调用者也可以确定线程在返回时的中断状态。
| 参数(Parameters) | |
|---|---|
blocker |
Object: the synchronization object responsible for this thread parking |
void parkNanos (Object blocker, long nanos)
除非许可证可用,否则为了线程调度目的禁用当前线程,直到指定的等待时间。
如果许可证可用,则它被消耗并且呼叫立即返回; 否则当前线程因为线程调度目的而被禁用,并且处于休眠状态,直到发生以下四种情况之一:
unpark with the current thread as the target; or 这种方法不报告是哪个线程导致该方法返回。 来电者应重新检查导致线头停放的条件。 例如,调用者也可以确定线程的中断状态,或返回时的经过时间。
| 参数(Parameters) | |
|---|---|
blocker |
Object: the synchronization object responsible for this thread parking |
nanos |
long: the maximum number of nanoseconds to wait |
void parkNanos (long nanos)
除非许可证可用,否则为了线程调度目的禁用当前线程,直到指定的等待时间。
如果许可证可用,则它被消耗并且呼叫立即返回; 否则当前线程因为线程调度目的而被禁用,并且处于休眠状态,直到发生以下四种情况之一:
unpark with the current thread as the target; or 这种方法不报告是哪个线程导致该方法返回。 来电者应重新检查导致线头停放的条件。 例如,调用者也可以确定线程的中断状态,或返回时的经过时间。
| 参数(Parameters) | |
|---|---|
nanos |
long: the maximum number of nanoseconds to wait |
void parkUntil (Object blocker, long deadline)
禁用当前线程以进行线程调度,直到指定的截止日期,除非许可证可用。
如果许可证可用,则它被消耗并且呼叫立即返回; 否则当前线程因为线程调度目的而被禁用,并且处于休眠状态,直到发生以下四种情况之一:
unpark with the current thread as the target; or 这种方法不报告是哪个线程导致该方法返回。 来电者应重新检查导致线头停放的条件。 例如,调用者也可以确定线程的中断状态,或返回时的当前时间。
| 参数(Parameters) | |
|---|---|
blocker |
Object: the synchronization object responsible for this thread parking |
deadline |
long: the absolute time, in milliseconds from the Epoch, to wait until |
void parkUntil (long deadline)
禁用当前线程以进行线程调度,直到指定的截止日期,除非许可证可用。
如果许可证可用,则它被消耗并且呼叫立即返回; 否则当前线程因为线程调度目的而被禁用,并且处于休眠状态,直到发生以下四种情况之一:
unpark with the current thread as the target; or 这种方法不报告是哪个线程导致该方法返回。 来电者应重新检查导致线头停放的条件。 例如,调用者也可以确定线程的中断状态,或返回时的当前时间。
| 参数(Parameters) | |
|---|---|
deadline |
long: the absolute time, in milliseconds from the Epoch, to wait until |
void unpark (Thread thread)
如果该线程尚不可用,则为该线程提供许可证。 如果该线程在park上被阻止,则它将解除阻止。 否则,它保证不会阻止对park下一次呼叫。 如果给定线程尚未启动,则此操作不能保证完全有效。
| 参数(Parameters) | |
|---|---|
thread |
Thread: the thread to unpark, or null, in which case this operation has no effect |