Module  java.base

Class LockSupport



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

    这个类与每个使用它的线程关联,允许(在Semaphore类的意义上)。 如果许可证可用,则在park的电话将立即返回,在此过程中消耗许可证; 否则可能会阻止。 致电unpark使许可证可用,如果尚未提供。 (与信号量不同,尽管许可证不能累积,最多只有一个。)可靠的使用需要使用volatile(或atomic)变量来控制何时停放或取消标记。 对于易失性变量访问,维护对这些方法的调用排序,但不一定是非易失性变量访问。

    方法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任何中介使用(包括通过类加载隐式)可能导致无响应的线程(“丢失的未标记”)。

    样品用法。 这是一个先入先出的非可重入锁类的草图:

       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
    • 方法摘要

      所有方法  静态方法  具体的方法 
      Modifier and Type 方法 描述
      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 - 如果参数为空
        从以下版本开始:
        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 - 绝对时间,以毫秒为单位,从时代到等到