模块 java.base

类 ReentrantLock

java.lang.Object
java.util.concurrent.locks.ReentrantLock
所有已实现的接口:
Serializable , Lock

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

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

此类的构造函数接受一个可选的 fairness 参数。当设置 true 时,在争用下,锁倾向于授予对等待时间最长的线程的访问权限。否则此锁不保证任何特定的访问顺序。使用由许多线程访问的公平锁的程序可能会显示比使用默认设置的程序更低的总体吞吐量(即,更慢;通常更慢),但在获取锁和保证不会出现饥饿的时间方面差异较小。但是请注意,锁的公平性并不能保证线程调度的公平性。因此,许多使用公平锁的线程之一可能会连续多次获得它,而其他活动线程没有进展并且当前没有持有锁。另请注意,未计时的 tryLock() 方法不遵守公平设置。如果锁可用,即使其他线程正在等待,它也会成功。

建议 always 立即调用带有 try 块的 lock ,最典型的是在前/后构造中,例如:

 
 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
参见:
  • 构造方法详细信息

    • ReentrantLock

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

      public ReentrantLock(boolean fair)
      使用给定的公平策略创建 ReentrantLock 的实例。
      参数:
      fair - true 如果这个锁应该使用公平排序策略
  • 方法详情

    • lock

      public void lock()
      获取锁。

      如果锁没有被另一个线程持有,则获取锁并立即返回,将锁持有计数设置为 1。

      如果当前线程已经持有锁,则持有计数加一,方法立即返回。

      如果锁被另一个线程持有,则当前线程出于线程调度目的而被禁用并处于休眠状态,直到获得锁,此时锁持有计数被设置为 1。

      指定者:
      lock 在接口 Lock
    • lockInterruptibly

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

      如果锁没有被另一个线程持有,则获取锁并立即返回,将锁持有计数设置为 1。

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

      如果锁由另一个线程持有,则当前线程将出于线程调度目的而被禁用并处于休眠状态,直到发生以下两种情况之一:

      • 锁由当前线程获取;或者
      • 一些其他线程 中断 当前线程。

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

      如果当前线程:

      • 在进入此方法时设置其中断状态;或者
      • 获取锁时是interrupted
      然后抛出InterruptedException 并清除当前线程的中断状态。

      在此实现中,由于此方法是显式中断点,因此优先响应中断而不是正常或可重入获取锁。

      指定者:
      lockInterruptibly 在接口 Lock
      抛出:
      InterruptedException - 如果当前线程被中断
    • tryLock

      public boolean tryLock()
      仅当调用时锁未被另一个线程持有时才获取锁。

      如果锁未被另一个线程持有,则获取锁并立即返回值 true ,将锁持有计数设置为 1。即使已将此锁设置为使用公平排序策略,对 tryLock() will 的调用也会在可用时立即获取锁,无论其他线程当前是否正在等待锁。这种“闯入”行为在某些情况下可能很有用,即使它破坏了公平性。如果你想遵守这个锁的公平设置,那么使用几乎等效的tryLock(0, TimeUnit.SECONDS) (它也检测中断)。

      如果当前线程已经持有此锁,则持有计数递增 1,并且该方法返回 true

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

      指定者:
      tryLock 在接口 Lock
      返回:
      true 如果锁是空闲的并且被当前线程获取,或者锁已经被当前线程持有;和false否则
    • tryLock

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

      如果锁未被另一个线程持有,则获取锁并立即返回值 true ,将锁持有计数设置为 1。如果此锁已设置为使用公平排序策略,则在任何其他线程正在等待锁的情况下,将获取可用锁will not。这与 tryLock() 方法形成对比。如果你想要一个允许闯入公平锁的定时tryLock,那么将定时和非定时形式组合在一起:

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

      如果当前线程已经持有此锁,则持有计数递增 1,并且该方法返回 true

      如果锁由另一个线程持有,则当前线程将因线程调度目的而被禁用并处于休眠状态,直到发生以下三种情况之一:

      • 锁由当前线程获取;或者
      • 一些其他线程中断当前线程;或者
      • 指定的等待时间结束

      如果获得锁,则返回值 true 并将锁保持计数设置为 1。

      如果当前线程:

      • 在进入此方法时设置其中断状态;或者
      • 获取锁时是interrupted
      然后抛出InterruptedException 并清除当前线程的中断状态。

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

      在此实现中,由于此方法是一个显式中断点,因此优先响应中断而不是正常或重入获取锁,并优先报告等待时间的流逝。

      指定者:
      tryLock 在接口 Lock
      参数:
      timeout - 等待锁的时间
      unit - 超时参数的时间单位
      返回:
      true 如果锁是空闲的并且被当前线程获取,或者锁已经被当前线程持有;和 false 如果在获取锁之前等待时间已经过去
      抛出:
      InterruptedException - 如果当前线程被中断
      NullPointerException - 如果时间单位为空
    • unlock

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

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

      指定者:
      unlock 在接口 Lock
      抛出:
      IllegalMonitorStateException - 如果当前线程没有持有这个锁
    • newCondition

      public Condition  newCondition()
      返回与此 Lock 实例一起使用的 Condition 实例。

      当与内置监视器锁一起使用时,返回的 Condition 实例支持与 Object 监视器方法(wait notify notifyAll )相同的用法。

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

      public int getHoldCount()
      查询当前线程持有此锁的次数。

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

      保持计数信息通常仅用于测试和调试目的。例如,如果某段代码不应该在已经持有锁的情况下进入,那么我们可以断言这个事实:

       
       class X {
        final 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 {
        final ReentrantLock lock = new ReentrantLock();
        // ...
      
        public void m() {
          assert lock.isHeldByCurrentThread();
          // ... method body
        }
       } 

      它还可用于确保以不可重入方式使用可重入锁,例如:

       
       class X {
        final 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 如果此锁的公平设置为真
    • 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
      重写:
      toString 在类 Object
      返回:
      标识此锁及其锁定状态的字符串