JavaTM 2 Platform
Standard Ed. 5.0

java.util.concurrent.locks
类 ReentrantLock

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

public class ReentrantLock
extends Object
implements Lock, Serializable

一个可重入的互斥锁定 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁定相同的一些基本行为和语义,但功能更强大。

ReentrantLock 将由最近成功获得锁定,并且还没有释放该锁定的线程所拥有。当锁定没有被另一个线程所拥有时,调用 lock 的线程将成功获取该锁定并返回。如果当前线程已经拥有该锁定,此方法将立即返回。可以使用 isHeldByCurrentThread()getHoldCount() 方法来检查此情况是否发生。

此类的构造方法接受一个可选的公平 参数。当设置为 true 时,在多个线程的争用下,这些锁定倾向于将访问权授予等待时间最长的线程。否则此锁定将无法保证任何特定访问顺序。与采用默认设置(使用不公平锁定)相比,使用公平锁定的程序在许多线程访问时表现为很低的总体吞吐量(即速度很慢,常常极其慢),但是在获得锁定和保证锁定分配的均衡性时差异较小。不过要注意的是,公平锁定不能保证线程调度的公平性。因此,使用公平锁定的众多线程中的一员可能获得多倍的成功机会,这种情况发生在其他活动线程没有被处理并且目前并未持有锁定时。还要注意的是,未定时的 tryLock 方法并没有使用公平设置。因为即使其他线程正在等待,只要该锁定是可用的,此方法就可以获得成功。

建议总是 立即实践,使用 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 接口,此类还定义了 isLockedgetLockQueueLength 方法,以及一些相关的 protected 访问方法,这些方法对检测和监视可能很有用。

该类的序列化与内置锁定的行为方式相同:一个反序列化的锁定处于解除锁定状态,不管它被序列化时的状态是怎样的。

此锁定最多支持同一个线程发起的 2147483648 个递归锁定。

从以下版本开始:
1.5
另请参见:
序列化表格

构造方法摘要
ReentrantLock()
          创建一个 ReentrantLock 的实例。
ReentrantLock(boolean fair)
          创建一个具有给定公平策略的 ReentrantLock
 
方法摘要
 int getHoldCount()
          查询当前线程保持此锁定的次数。
protected  Thread getOwner()
          返回目前拥有此锁定的线程,如果此锁定不被任何线程拥有,则返回 null
protected  Collection<Thread> getQueuedThreads()
          返回一个 collection,它包含可能正等待获取此锁定的线程。
 int getQueueLength()
          返回正等待获取此锁定的线程估计数。
protected  Collection<Thread> getWaitingThreads(Condition condition)
          返回一个 collection,它包含可能正在等待与此锁定相关给定条件的那些线程。
 int getWaitQueueLength(Condition condition)
          返回等待与此锁定相关的给定条件的线程估计数。
 boolean hasQueuedThread(Thread thread)
          查询给定线程是否正在等待获取此锁定。
 boolean hasQueuedThreads()
          查询是否有些线程正在等待获取此锁定。
 boolean hasWaiters(Condition condition)
          查询是否有些线程正在等待与此锁定有关的给定条件。
 boolean isFair()
          如果此锁定的公平设置为 true,则返回 true。
 boolean isHeldByCurrentThread()
          查询当前线程是否保持此锁定。
 boolean isLocked()
          查询此锁定是否由任意线程保持。
 void lock()
          获取锁定。
 void lockInterruptibly()
          如果当前线程未被中断,则获取锁定。
 Condition newCondition()
          返回用来与此 Lock 实例一起使用的 Condition 实例。
 String toString()
          返回标识此锁定及其锁定状态的字符串。
 boolean tryLock()
          仅在调用时锁定未被另一个线程保持的情况下,才获取该锁定。
 boolean tryLock(long timeout, TimeUnit unit)
          如果锁定在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁定。
 void unlock()
          试图释放此锁定。
 
从类 java.lang.Object 继承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

构造方法详细信息

ReentrantLock

public ReentrantLock()
创建一个 ReentrantLock 的实例。这等同于使用 ReentrantLock(false)


ReentrantLock

public ReentrantLock(boolean fair)
创建一个具有给定公平策略的 ReentrantLock

参数:
fair - 如果此锁定是公平的,则该参数为 true;否则为 false
方法详细信息

lock

public void lock()
获取锁定。

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

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

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

指定者:
接口 Lock 中的 lock

lockInterruptibly

public void lockInterruptibly()
                       throws InterruptedException
如果当前线程未被中断,则获取锁定。

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

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

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

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

如果当前线程:

则抛出 InterruptedException,并且清除当前线程的已中断状态。

在此实现中,因为此方法是一个显式中断点,所以要优先考虑响应中断,而不是响应锁定的普通获取或重入获取。

指定者:
接口 Lock 中的 lockInterruptibly
抛出:
InterruptedException - 如果当前线程已中断。
另请参见:
Thread.interrupt()

tryLock

public boolean tryLock()
仅在调用时锁定未被另一个线程保持的情况下,才获取该锁定。

如果该锁定没有被另一个线程保持,并且立即返回 true 值,则将锁定的保持计数设置为 1。即使已将此锁定设置为使用公平排序策略,但是调用 tryLock() 立即获取锁定(如果有可用的),而不管其他线程当前是否正在等待该锁定。在某些情况下,此“闯入”行为可能很有用,即使它会打破公平性也如此。如果希望遵守此锁定的公平设置,则使用 tryLock(0, TimeUnit.SECONDS) ,它几乎是等效的(也检测中断)。

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

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

指定者:
接口 Lock 中的 tryLock
返回:
如果锁定是自由的并且被当前线程获取,或者当前线程已经保持该锁定,则返回 true;否则返回 false

tryLock

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

如果该锁定没有被另一个线程保持,并且立即返回 true 值,则将锁定的保持计数设置为 1。如果为了使用公平的排序策略,已经设置此锁定,并且其他线程都在等待该锁定,则不会 获取一个可用的锁定。这与 tryLock() 方法相反。如果想使用一个允许闯入公平锁定的定时 tryLock,那么可以将定时形式和不定时形式组合在一起:

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

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

如果锁定被另一个线程保持,则出于线程调度目的,禁用当前线程,并且在发生以下三种情况之一以前,该线程将一直处于休眠状态:

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

如果当前线程:

则抛出 InterruptedException,并且清除当前线程的已中断状态。

如果超出了指定的等待时间,则返回值为 false。如果该时间小于或等于 0,则此方法根本不会等待。

在此实现中,因为此方法是一个显式中断点,所以要优先考虑响应中断,而不是响应锁定的普通获取或重入获取,或者报告所用的等待时间。

指定者:
接口 Lock 中的 tryLock
参数:
timeout - 等待锁定的时间
unit - timeout 参数的时间单位
返回:
如果锁定是自由的并且由当前线程获取,或者当前线程已经保持该锁定,则返回 true;如果在获取该锁定之前已经到达等待时间,则返回 false
抛出:
InterruptedException - 如果当前线程被中断
NullPointerException - 如果单位为 null
另请参见:
Thread.interrupt()

unlock

public void unlock()
试图释放此锁定。

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

指定者:
接口 Lock 中的 unlock
抛出:
IllegalMonitorStateException - 如果当前线程没有保持此锁定。

newCondition

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

在使用内置监视器锁定时,返回的 Condition 实例支持与 Object 的监视器方法(waitnotifynotifyAll)相同的用法。

指定者:
接口 Lock 中的 newCondition
返回:
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();
     }
   }
 }
 

返回:
当前线程保持此锁定的次数,如果此锁定未被当前线程保持过,则返回 0。

isHeldByCurrentThread

public boolean isHeldByCurrentThread()
查询当前线程是否保持此锁定。

与内置监视器锁定的 Thread.holdsLock(java.lang.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 - 如果 thread 为 null。

getQueueLength

public final int getQueueLength()
返回正等待获取此锁定的线程估计数。该值仅是估计的数字,因为在此方法遍历内部数据结构的同时,线程的数目可能动态地变化。此方法用于监视系统状态,不用于同步控制。

返回:
正在等待此锁定的线程估计数。

getQueuedThreads

protected Collection<Thread> getQueuedThreads()
返回一个 collection,它包含可能正等待获取此锁定的线程。因为在构造此结果的同时实际的线程 set 可能动态地变化,所以返回的 collection 仅是尽力的估计值。所返回 collection 中的元素没有特定的顺序。此方法用于加快子类的构造速度,以提供更多的监视设施。

返回:
线程的 collection。

hasWaiters

public boolean hasWaiters(Condition condition)
查询是否有些线程正在等待与此锁定有关的给定条件。注意,因为随时可能发生超时和中断,所以返回 true 并不保证将来某个 signal 将唤醒线程。此方法主要用于监视系统状态。

参数:
condition - 条件
返回:
如果有任何等待的线程,则返回 true
抛出:
IllegalMonitorStateException - 如果没有保持此锁定
IllegalArgumentException - 如果给定 condition 与此锁定无关
NullPointerException - 如果 condition 为 null

getWaitQueueLength

public int getWaitQueueLength(Condition condition)
返回等待与此锁定相关的给定条件的线程估计数。注意,因为随时可能发生超时和中断,所以只能将估计值作为实际等待线程数的上边界。此方法用于监视系统状态,不用于同步控制。

参数:
condition - 条件
返回:
等待线程的估计数。
抛出:
IllegalMonitorStateException - 如果没有保持此锁定
IllegalArgumentException - 如果给定 condition 与此锁定无关
NullPointerException - 如果 condition 为 null

getWaitingThreads

protected Collection<Thread> getWaitingThreads(Condition condition)
返回一个 collection,它包含可能正在等待与此锁定相关给定条件的那些线程。因为在构造此结果的同时实际的线程 set 可能动态地变化,所以返回 collection 的元素只是尽力的估计值。所返回 collection 中的元素没有特定的顺序。此方法用于加快子类的构造速度,提供更多的条件监视设施。

参数:
condition - 条件
返回:
线程的 collection
抛出:
IllegalMonitorStateException - 如果没有保持此锁定
IllegalArgumentException - 如果给定 condition 与此锁定无关
NullPointerException - 如果 condition 为 null

toString

public String toString()
返回标识此锁定及其锁定状态的字符串。该状态括在括号中,它包括字符串 "Unlocked" 或字符串 "Locked by",后跟拥有线程的 Thread.getName()

覆盖:
Object 中的 toString
返回:
标识此锁定及其锁定状态的字符串。

JavaTM 2 Platform
Standard Ed. 5.0

提交错误或意见
有关更多的 API 参考资料和开发人员文档,请参阅 Java 2 SDK SE 开发人员文档。该文档包含更详细的、面向开发人员的描述,以及总体概述、术语定义、使用技巧和工作代码示例。

版权所有 2004 Sun Microsystems, Inc. 保留所有权利。 请遵守许可证条款。另请参阅文档重新分发政策