Module  java.base

Class ReentrantLock

  • All Implemented Interfaces:
    SerializableLock


    public class ReentrantLock
    extends Object
    implements Lock, Serializable
    可重入互斥Lock具有与使用synchronized方法和语句访问的隐式监视锁相同的基本行为和语义,但具有扩展功能。

    A ReentrantLock由线程拥有 ,最后成功锁定,但尚未解锁。 调用lock的线程将返回,当锁不是由另一个线程拥有时,成功获取锁。 如果当前线程已经拥有该锁,该方法将立即返回。 这可以使用方法isHeldByCurrentThread()getHoldCount()进行检查。

    该类的构造函数接受可选的公平参数。 设置true ,在争用的情况下,锁有利于授予对最长等待线程的访问权限。 否则,该锁不保证任何特定的访问顺序。 使用许多线程访问的公平锁的程序可能会比使用默认设置的整体吞吐量(即,更慢,通常要慢得多),但是具有更小的差异来获得锁定并保证缺乏饥饿。 但是请注意,锁的公平性不能保证线程调度的公平性。 因此,使用公平锁的许多线程之一可以连续获得多次,而其他活动线程不进行而不是当前持有锁。 另请注意,未定义的tryLock()方法不符合公平性设置。 如果锁可用,即使其他线程正在等待,它也会成功。

    建议您务必立即致电locktry块,最典型的是在之前/之后施工,如:

       class X { private final ReentrantLock lock = new ReentrantLock(); // ... public void m() { lock.lock(); // block until condition holds try { // ... method body } finally { lock.unlock() } } } 

    除了实现Lock接口,该类还定义了一些publicprotected方法来检查锁的状态。 其中一些方法仅适用于仪器和监控。

    此类的序列化与内置锁的操作方式相同:反序列化锁处于未锁定状态,无论其序列化时的状态如何。

    此锁最多支持同一个线程的2147483647递归锁。 超过此限制的尝试将导致Error从锁定方法中抛出。

    从以下版本开始:
    1.5
    另请参见:
    Serialized Form
    • 构造方法详细信息

      • ReentrantLock

        public ReentrantLock​()
        创建一个ReentrantLock的实例。 这相当于使用ReentrantLock(false)
      • ReentrantLock

        public ReentrantLock​(boolean fair)
        使用给定的公平政策创建 ReentrantLock的实例。
        参数
        fair - true如果此锁应使用合理的订购策略
    • 方法详细信息

      • lock

        public void lock​()
        获得锁。

        如果锁没有被另一个线程占用并且立即返回,则将锁定计数设置为1。

        如果当前线程已经保持锁定,则保持计数增加1,该方法立即返回。

        如果锁被另一个线程保持,则当前线程将被禁用以进行线程调度,并且在锁定已被获取之前处于休眠状态,此时锁定保持计数被设置为1。

        Specified by:
        lock在接口 Lock
      • lockInterruptibly

        public void lockInterruptibly​()
                               throws InterruptedException
        获取锁定,除非当前线程是interrupted

        如果锁没有被另一个线程占用并且立即返回,则将锁定计数设置为1。

        如果当前线程已经保存此锁,则保持计数将递增1,该方法立即返回。

        如果锁被另一个线程保持,则当前线程将被禁用以进行线程调度,并且处于休眠状态,直到发生两件事情之一:

        • 锁是由当前线程获取的; 要么
        • 一些其他线程当前线程interrupts

        如果当前线程获取锁定,则锁定保持计数被设置为1。

        如果当前线程:

        • 在进入该方法时设置了中断状态; 要么
        • interrupted同时获取锁,
        然后抛出InterruptedException ,并清除当前线程的中断状态。

        在该实现中,由于该方法是明确的中断点,所以优先考虑通过锁定正常或可重入的采集来响应中断。

        Specified by:
        lockInterruptibly在接口 Lock
        异常
        InterruptedException - 当前线程是否中断
      • tryLock

        public boolean tryLock​()
        只有在调用时它不被另一个线程占用才能获取锁。

        如果锁定不被另一个线程true并且立即返回值true ,将锁定保持计数设置为1,则获取锁定。 即使此锁已设置为使用合理的排序策略,如果可用,则呼叫tryLock() 立即获取锁,无论其他线程是否正在等待锁定。 这种“趸船”行为在某些情况下是有用的,尽管它打破了公平。 如果要遵守该锁的公平性设置,则使用tryLock(0, TimeUnit.SECONDS) 几乎相当(也检测到中断)。

        如果当前线程已经保存该锁,则保持计数增加1,该方法返回true

        如果锁由另一个线程持有,则该方法将立即返回值为false

        Specified by:
        tryLock接口 Lock
        结果
        true如果锁是空闲的并且被当前线程获取,或者锁已经被当前线程保持; 而另外false
      • tryLock

        public boolean tryLock​(long timeout,
                               TimeUnit unit)
                        throws InterruptedException
        如果在给定的等待时间内没有被另一个线程占用 ,并且当前线程尚未被interrupted获取锁定

        获取锁定,如果没有被另一个线程保持,并立即返回值true ,将锁定保持计数设置为1。 如果此锁已设置为使用合理的排序策略,则如果任何其他线程正在等待锁定, 则不会获取可用的锁。 这与tryLock()方法不同。 如果你想要一个定时的tryLock ,允许在公平的锁定驳船,那么将定时和非定时的形式组合在一起:

           if (lock.tryLock() || lock.tryLock(timeout, unit)) { ... } 

        如果当前线程已经保存该锁,则保持计数增加1,该方法返回true

        如果锁被另一个线程保持,则当前线程将被禁用以进行线程调度,并且处于休眠状态,直至发生三件事情之一:

        • 锁是由当前线程获取的; 要么
        • 一些其他线程当前线程interrupts ; 要么
        • 指定的等待时间过去了

        如果锁获取,则返回值true ,锁定保持计数设置为1。

        如果当前线程:

        • 在进入该方法时设置了中断状态; 要么
        • interrupted同时获取锁,
        然后抛出InterruptedException ,并清除当前线程的中断状态。

        如果指定的等待时间过去,则返回值false 如果时间小于或等于零,该方法根本不会等待。

        在这种实现中,由于该方法是明确的中断点,所以优先考虑响应中断超过正常或可重入的锁的获取,并且报告等待时间的过去。

        Specified by:
        tryLock在接口 Lock
        参数
        timeout - 等待锁的时间
        unit - 超时参数的时间单位
        结果
        true如果锁是空闲的并且被当前线程获取,或者锁已经被当前线程保持; 如果可以获取锁定之前经过的等待时间, false
        异常
        InterruptedException - 当前线程是否中断
        NullPointerException - 如果时间单位为空
      • unlock

        public void unlock​()
        尝试释放此锁。

        如果当前线程是该锁的持有者,则保持计数递减。 如果保持计数现在为零,则锁定被释放。 如果当前线程不是该锁的持有者,则抛出IllegalMonitorStateException

        Specified by:
        unlock在接口 Lock
        异常
        IllegalMonitorStateException - 如果当前线程不持有此锁
      • newCondition

        public Condition newCondition​()
        返回Condition与此使用实例Lock实例。

        返回Condition实例支持相同的用途为做Object监视器方法( waitnotify ,并notifyAll与使用时)内置监视器锁定。

        • 如果在调用任何Condition waitingsignalling方法时未锁定此锁,则抛出IllegalMonitorStateException
        • 当条件waiting方法被调用时,锁将被释放,并且在它们返回之前,重新获取锁并且锁定保持计数恢复为调用该方法时的值。
        • 如果一个线程是interrupted,而等待,则等待将终止,则会抛出一个InterruptedException ,线程的中断状态将被清除。
        • 等待线程以FIFO顺序发出信号。
        • 从等待方法返回的线程的锁重新获取的顺序与初始获取锁的线程相同,这在默认情况下未指定,但是对于公平的锁有利于那些等待最长的线程。
        Specified by:
        newCondition在接口 Lock
        结果
        Condition对象
      • getHoldCount

        public int getHoldCount​()
        查询当前线程对此锁的暂停数量。

        一个线程对于与解锁动作不匹配的每个锁定动作都有一个锁定。

        保持计数信息通常仅用于测试和调试目的。 例如,如果一段代码不应该被锁定,那么我们可以断言这个事实:

           class X { ReentrantLock lock = new ReentrantLock(); // ... public void m() { assert lock.getHoldCount() == 0; lock.lock(); try { // ... method body } finally { lock.unlock(); } } } 
        结果
        当前线程对此锁定的保持次数,如果此锁定不由当前线程保持,则为零
      • isHeldByCurrentThread

        public boolean isHeldByCurrentThread​()
        查询此锁是否由当前线程持有。

        类似于内置监视器锁的Thread.holdsLock(Object)方法,该方法通常用于调试和测试。 例如,只有在锁定时才应该调用的方法可以断言是这样的:

           class X { ReentrantLock lock = new ReentrantLock(); // ... public void m() { assert lock.isHeldByCurrentThread(); // ... method body } } 

        它也可以用于确保以非折返方式使用折返锁,例如:

           class X { ReentrantLock lock = new ReentrantLock(); // ... public void m() { assert !lock.isHeldByCurrentThread(); lock.lock(); try { // ... method body } finally { lock.unlock(); } } } 
        结果
        true如果当前线程持有该锁,否则为 false
      • isLocked

        public boolean isLocked​()
        查询此锁是否由任何线程持有。 该方法设计用于监视系统状态,不用于同步控制。
        结果
        true如果任何线程持有此锁,否则为 false
      • isFair

        public final boolean isFair​()
        如果此锁的公平设置为true,则返回 true
        结果
        true如果这个锁的公平设置为true
      • getOwner

        protected Thread getOwner​()
        返回当前拥有此锁的线程,如果不拥有,则返回null 当这个方法被不是所有者的线程调用时,返回值反映了当前锁定状态的尽力近似。 例如,即使有线程试图获取锁定但还没有这样做,所有者可能暂时是null 该方法旨在便于构建提供更广泛的锁定监控设施的子类。
        结果
        所有者,或 null如果不拥有
      • hasQueuedThreads

        public final boolean hasQueuedThreads​()
        查询是否有线程正在等待获取此锁。 请注意,由于取消可能随时发生,因此true返回不能保证任何其他线程将获得此锁。 该方法主要用于监视系统状态。
        结果
        true如果可能有其他线程等待获取锁
      • hasQueuedThread

        public final boolean hasQueuedThread​(Thread thread)
        查询给定线程是否等待获取此锁。 请注意,由于取消可能随时发生,因此true返回不能保证此线程将获取此锁。 该方法主要用于监视系统状态。
        参数
        thread - 线程
        结果
        true如果给定的线程排队等待此锁
        异常
        NullPointerException - 如果线程为空
      • getQueueLength

        public final int getQueueLength​()
        返回等待获取此锁的线程数的估计。 该值只是一个估计,因为线程数可能会在此方法遍历内部数据结构时动态更改。 该方法设计用于监控系统状态,不用于同步控制。
        结果
        估计等待这个锁的线程数
      • getQueuedThreads

        protected Collection<Thread> getQueuedThreads​()
        返回包含可能正在等待获取此锁的线程的集合。 因为在构建此结果时,实际的线程集可能会动态更改,所以返回的集合只是尽力而为的估计。 返回的集合的元素没有特定的顺序。 该方法旨在便于构建提供更广泛监控设施的子类。
        结果
        线程的收集
      • hasWaiters

        public boolean hasWaiters​(Condition condition)
        查询任何线程是否等待与此锁相关联的给定条件。 请注意,由于超时和中断可能随时发生,因此true返回不能保证未来的任何线程将唤醒signal 该方法主要用于监视系统状态。
        参数
        condition - 条件
        结果
        true如果有任何等待线程
        异常
        IllegalMonitorStateException - 如果此锁没有保持
        IllegalArgumentException - 如果给定的条件与此锁没有关联
        NullPointerException - 如果条件为空
      • getWaitQueueLength

        public int getWaitQueueLength​(Condition condition)
        返回与此锁相关联的给定条件等待的线程数的估计。 请注意,由于超时和中断可能在任何时间发生,估计仅作为实际服务员人数的上限。 该方法设计用于监视系统状态,不用于同步控制。
        参数
        condition - 条件
        结果
        估计等待线程数
        异常
        IllegalMonitorStateException - 如果此锁不被保留
        IllegalArgumentException - 如果给定的条件不与此锁相关联
        NullPointerException - 如果条件为空
      • getWaitingThreads

        protected Collection<Thread> getWaitingThreads​(Condition condition)
        返回包含可能在与此锁相关联的给定条件下等待的线程的集合。 因为在构建此结果时,实际的线程集可能会动态更改,所以返回的集合只是尽力而为的估计。 返回的集合的元素没有特定的顺序。 该方法旨在便于构建提供更广泛的状态监测设施的子类。
        参数
        condition - 条件
        结果
        线程的收集
        异常
        IllegalMonitorStateException - 如果此锁没有保持
        IllegalArgumentException - 如果给定的条件不与此锁相关联
        NullPointerException - 条件为空
      • toString

        public String toString​()
        返回一个标识此锁的字符串以及其锁定状态。 括号中的状态包括字符串"Unlocked"或字符串"Locked by"后跟所拥有的线程的name
        重写:
        toStringObject
        结果
        标识此锁的字符串以及其锁定状态