该类为使用它的每个线程关联一个许可(在Semaphore
类的意义上)。如果许可可用,则调用park
将立即返回并在过程中消耗它;否则它可能会阻塞。调用unpark
会使许可可用,如果它尚未可用。(不像Semaphore,许可不会累积。最多只有一个。)可靠的使用需要使用volatile(或原子)变量来控制何时park或unpark。对这些方法的调用顺序与volatile变量访问相关,但不一定与非volatile变量访问相关。
方法park
和unpark
提供了有效的阻塞和解除阻塞线程的方法,不会遇到导致废弃的Thread.suspend
和Thread.resume
方法无法用于此类目的的问题:一个线程调用park
,另一个线程尝试unpark
之间的竞争将保持活跃性,由于许可。此外,如果调用者的线程被中断,park
将返回,并支持超时版本。park
方法也可能在任何其他时间返回,"无缘无故",因此通常必须在返回时在循环内调用以重新检查条件。在这种意义上,park
作为"忙等待"的优化,不会浪费太多时间旋转,但必须与unpark
配对才能有效。
park
的三种形式还支持一个blocker
对象参数。该对象在线程被阻塞时记录,以允许监视和诊断工具识别线程被阻塞的原因。(这些工具可以使用方法getBlocker(Thread)
访问阻塞器。)强烈建议使用这些带有此参数的形式,而不是原始形式。在锁实现中作为blocker
提供的正常参数是this
。
这些方法旨在用作创建更高级别同步工具的工具,并且本身对于大多数并发控制应用程序并不实用。park
方法仅设计用于以下形式的构造:
while (!canProceed()) {
// 确保对其他线程可见的unpark请求
...
LockSupport.park(this);
}
其中线程发布解锁请求之前的任何操作,在调用park
之前,不涉及锁定或阻塞。因为每个线程只关联一个许可,任何中间使用park
,包括隐式通过类加载,都可能导致无响应的线程("丢失的unpark")。
- 自:
- 1.5
-
Method Summary
Modifier and TypeMethodDescriptionstatic Object
getBlocker
(Thread t) 返回最近一次调用的park方法提供的阻塞对象,该方法尚未解除阻塞,如果未阻塞则返回null。static void
park()
除非许可可用,否则为线程调度目的禁用当前线程。static void
除非许可可用,否则为线程调度目的禁用当前线程。static void
parkNanos
(long nanos) 除非许可可用,否则为指定的等待时间禁用当前线程以进行线程调度目的。static void
除非许可可用,否则为指定的等待时间禁用当前线程以进行线程调度目的。static void
parkUntil
(long deadline) 除非许可可用,否则为线程调度目的禁用当前线程,直到指定的截止日期。static void
除非许可可用,否则为线程调度目的禁用当前线程,直到指定的截止日期。static void
setCurrentBlocker
(Object blocker) 设置要由当前线程的getBlocker
调用返回的对象。static void
为给定线程提供许可,如果尚未可用。
-
Method Details
-
setCurrentBlocker
设置要由当前线程的getBlocker
调用返回的对象。可以在从非公共对象调用无参数版本的park()
之前使用此方法,以允许更有用的诊断,或保留与以前的阻塞方法实现的兼容性。在阻塞后,不会自动恢复阻塞器的先前值。要获得park(b
}的效果,请使用setCurrentBlocker(b); park(); setCurrentBlocker(null);
- 参数:
-
blocker
- 阻塞对象 - 自:
- 14
-
unpark
为给定线程提供许可,如果尚未可用。如果线程在park
上被阻塞,则它将解除阻塞。否则,它的下一次调用park
保证不会阻塞。如果给定线程尚未启动,则不保证此操作会产生任何效果。- 参数:
-
thread
- 要解除阻塞的线程,或null
,在这种情况下此操作无效
-
park
除非许可可用,否则为线程调度目的禁用当前线程。如果许可可用,则它将被消耗并立即返回;否则当前线程将为线程调度目的而被禁用,并处于休眠状态,直到发生以下三种情况之一:
此方法不会报告导致方法返回的原因。调用者应重新检查导致线程最初park的条件。调用者还可以确定例如线程在返回时的中断状态。
- 参数:
-
blocker
- 负责此线程停放的同步对象 - 自:
- 1.6
-
parkNanos
除非许可可用,否则为指定的等待时间禁用当前线程以进行线程调度目的。如果指定的等待时间为零或负数,则该方法不执行任何操作。否则,如果许可可用,则它将被消耗并立即返回;否则当前线程将为线程调度目的而被禁用,并处于休眠状态,直到发生以下四种情况之一:
此方法不会报告导致方法返回的原因。调用者应重新检查导致线程最初park的条件。调用者还可以确定例如线程的中断状态或返回时的经过时间。
- 参数:
-
blocker
- 负责此线程停放的同步对象 -
nanos
- 等待的最大纳秒数 - 自:
- 1.6
-
parkUntil
除非许可可用,否则为指定的截止日期禁用当前线程以进行线程调度目的。如果许可可用,则它将被消耗并立即返回;否则当前线程将为线程调度目的而被禁用,并处于休眠状态,直到发生以下四种情况之一:
此方法不会报告导致方法返回的原因。调用者应重新检查导致线程最初park的条件。调用者还可以确定例如线程的中断状态或返回时的当前时间。
- 参数:
-
blocker
- 负责此线程停放的同步对象 -
deadline
- 从纪元开始的毫秒绝对时间,等待直到 - 自:
- 1.6
-
getBlocker
返回最近一次调用的park方法提供的阻塞对象,该方法尚未解除阻塞,如果未阻塞则返回null。返回的值只是一个瞬时快照 -- 该线程可能已经解除阻塞或在不同的阻塞对象上阻塞。- 参数:
-
t
- 线程 - 返回:
- 阻塞器
- 抛出:
-
NullPointerException
- 如果参数为null - 自:
- 1.6
-
park
public static void park() -
parkNanos
public static void parkNanos(long nanos) 禁用当前线程以进行线程调度,最多等待指定的时间,除非许可证可用。如果指定的等待时间为零或负数,则该方法不执行任何操作。否则,如果许可证可用,则会被消耗并立即返回调用;否则,当前线程将被禁用以进行线程调度,并处于休眠状态,直到发生以下四种情况之一:
此方法不会报告导致方法返回的原因。调用者应重新检查导致线程最初停放的条件。调用者还可以在返回时确定线程的中断状态或经过的时间。
- 参数:
-
nanos
- 等待的最大纳秒数
-
parkUntil
public static void parkUntil(long deadline) 禁用当前线程以进行线程调度,直到指定的截止时间,除非许可证可用。如果许可证可用,则会被消耗并立即返回调用;否则,当前线程将被禁用以进行线程调度,并处于休眠状态,直到发生以下四种情况之一:
此方法不会报告导致方法返回的原因。调用者应重新检查导致线程最初停放的条件。调用者还可以在返回时确定线程的中断状态或当前时间。
- 参数:
-
deadline
- 等待的绝对时间,从纪元开始的毫秒数
-