- 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 ObjectgetBlocker(Thread t)返回提供给尚未解除阻塞的park方法的最新调用的阻止程序对象,如果未阻止,则返回null。static voidpark()除非许可证可用,否则禁用当前线程以进行线程调度。static voidpark(Object blocker)除非许可证可用,否则禁用当前线程以进行线程调度。static voidparkNanos(long nanos)除非许可证可用,否则禁用当前线程以进行线程调度,直到指定的等待时间。static voidparkNanos(Object blocker, long nanos)除非许可证可用,否则禁用当前线程以进行线程调度,直到指定的等待时间。static voidparkUntil(long deadline)除非许可证可用,否则禁用当前线程以进行线程调度,直到指定的截止时间。static voidparkUntil(Object blocker, long deadline)除非许可证可用,否则禁用当前线程以进行线程调度,直到指定的截止时间。static voidunpark(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- 从纪元开始,以毫秒为单位的绝对时间
- 其他一些线程调用
-
-