模块  java.base

Class LockSupport


  • public class LockSupport
    extends Object
    用于创建锁和其他同步类的基本线程阻塞原语。

    该类与使用它的每个线程关联一个许可证(在Semaphore类的意义上)。 如果许可证可用,将立即返回park ,并在此过程中消费; 否则可能会阻止。 如果尚未提供许可,则致电unpark获得许可。 (与Semaphores不同,许可证不会累积。最多只有一个。)可靠的使用需要使用volatile(或原子)变量来控制何时停放或取消停放。 对于易失性变量访问保持对这些方法的调用的顺序,但不一定是非易失性变量访问。

    方法parkunpark提供了阻止和解除阻塞线程的有效方法,这些线程没有遇到导致不推荐使用的方法Thread.suspendThread.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 - 从纪元开始,以毫秒为单位的绝对时间