- java.lang.Object
-
- java.util.concurrent.locks.ReentrantLock
-
- 实现的所有接口
-
Serializable,Lock
public class ReentrantLock extends Object implements Lock, Serializable
重入互斥Lock具有与使用synchronized方法和语句访问的隐式监视器锁相同的基本行为和语义,但具有扩展功能。ReentrantLock由最后成功锁定的线程拥有 ,但尚未解锁。 当锁不是由另一个线程拥有时,调用lock的线程将返回,成功获取锁。 如果当前线程已拥有锁,则该方法将立即返回。 这可以使用方法isHeldByCurrentThread()和getHoldCount()来检查。此类的构造函数接受可选的fairness参数。 当设置
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接口之外,此类还定义了许多用于检查锁定状态的public和protected方法。 其中一些方法仅适用于仪器和监测。此类的序列化与内置锁的行为方式相同:反序列化锁处于解锁状态,无论序列化时的状态如何。
此锁通过同一线程最多支持2147483647个递归锁。 尝试超过此限制会导致锁定方法引发
Error抛出。- 从以下版本开始:
- 1.5
- 另请参见:
- Serialized Form
-
-
构造方法摘要
构造方法 构造器 描述 ReentrantLock()创建一个ReentrantLock的实例。ReentrantLock(boolean fair)使用给定的公平策略创建ReentrantLock的实例。
-
方法摘要
所有方法 实例方法 具体的方法 变量和类型 方法 描述 intgetHoldCount()查询当前线程对此锁定的保持数。protected ThreadgetOwner()返回当前拥有此锁的线程,如果不拥有,则返回null。protected Collection<Thread>getQueuedThreads()返回包含可能正在等待获取此锁的线程的集合。intgetQueueLength()返回等待获取此锁的线程数的估计值。protected Collection<Thread>getWaitingThreads(Condition condition)返回一个集合,其中包含可能正在等待与此锁定关联的给定条件的那些线程。intgetWaitQueueLength(Condition condition)返回在与此锁定关联的给定条件上等待的线程数的估计值。booleanhasQueuedThread(Thread thread)查询给定线程是否正在等待获取此锁定。booleanhasQueuedThreads()查询是否有任何线程正在等待获取此锁。booleanhasWaiters(Condition condition)查询是否有任何线程正在等待与此锁定关联的给定条件。booleanisFair()如果此锁定的公平性设置为true,则返回true。booleanisHeldByCurrentThread()查询当前线程是否持有此锁定。booleanisLocked()查询此锁是否由任何线程持有。voidlock()获得锁。voidlockInterruptibly()除非当前线程是 interrupted,否则获取锁定。ConditionnewCondition()StringtoString()返回标识此锁的字符串及其锁定状态。booleantryLock()只有在调用时没有被另一个线程持有时才获取锁。booleantryLock(long timeout, TimeUnit unit)如果在给定的等待时间内没有被另一个线程持有并且当前线程不是 interrupted ,则获取锁。voidunlock()尝试释放此锁定。
-
-
-
方法详细信息
-
lock
public void lock()
获得锁。如果锁没有被另一个线程保持并获得锁定并立即返回,则将锁定保持计数设置为1。
如果当前线程已经保持锁定,则保持计数增加1并且该方法立即返回。
如果锁由另一个线程保持,那么当前线程将被禁用以进行线程调度,并且在获取锁之前处于休眠状态,此时锁定保持计数设置为1。
-
lockInterruptibly
public void lockInterruptibly() throws InterruptedException除非当前线程为interrupted,否则获取锁定。如果锁没有被另一个线程保持并获得锁定并立即返回,则将锁定保持计数设置为1。
如果当前线程已经保持此锁定,则保持计数加1,并且该方法立即返回。
如果锁由另一个线程持有,那么当前线程将被禁用以进行线程调度,并且在发生以下两种情况之一之前处于休眠状态:
- 锁定由当前线程获取; 要么
- 其他一些线程interrupts当前线程。
如果当前线程获取锁定,则锁定保持计数设置为1。
如果当前线程:
- 在进入此方法时设置其中断状态; 要么
- 获得锁定时是interrupted
InterruptedException并清除当前线程的中断状态。在该实现中,由于该方法是显式中断点,因此优先考虑通过正常或可重入获取锁来响应中断。
- Specified by:
-
lockInterruptibly,界面Lock - 异常
-
InterruptedException- 如果当前线程被中断
-
tryLock
public boolean tryLock()
只有在调用时没有被另一个线程持有时才获取锁。如果锁未被另一个线程持有,则获取锁,并立即返回值
true,将锁定保持计数设置为1。 即使已将此锁定设置为使用公平排序策略,对tryLock()的调用也会立即获取锁定(如果可用),无论其他线程当前是否正在等待锁定。 这种“闯入”行为在某些情况下可能有用,即使它违反了公平性。 如果您想要遵守此锁的公平性设置,请使用几乎相同的tryLock(0, TimeUnit.SECONDS)(它还会检测到中断)。如果当前线程已经保持此锁定,则保持计数加1,方法返回
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种监视器方法(wait,notify和notifyAll与使用时)内置监视器锁定。- 如果在调用任何
Conditionwaiting或signalling方法时未保持此锁定,则抛出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如果此锁定的公平性设置为真
-
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- 如果线程为null
-
getQueueLength
public final int getQueueLength()
返回等待获取此锁的线程数的估计值。 该值只是一个估计值,因为当此方法遍历内部数据结构时,线程数可能会动态更改。 此方法设计用于监视系统状态,而不是用于同步控制。- 结果
- 等待此锁定的估计线程数
-
getQueuedThreads
protected Collection<Thread> getQueuedThreads()
返回包含可能正在等待获取此锁的线程的集合。 因为实际的线程集可能在构造此结果时动态更改,所以返回的集合仅是尽力而为的估计。 返回集合的元素没有特定的顺序。 该方法旨在便于构建提供更广泛监控设施的子类。- 结果
- 线程集合
-
hasWaiters
public boolean hasWaiters(Condition condition)
查询是否有任何线程正在等待与此锁定关联的给定条件。 请注意,由于超时和中断可能随时发生,true返回并不能保证未来的signal会唤醒任何线程。 该方法主要用于监视系统状态。- 参数
-
condition- 条件 - 结果
-
true如果有任何等待线程 - 异常
-
IllegalMonitorStateException- 如果未保留此锁定 -
IllegalArgumentException- 如果给定条件与此锁无关 -
NullPointerException- 如果条件为null
-
getWaitQueueLength
public int getWaitQueueLength(Condition condition)
返回在与此锁定关联的给定条件上等待的线程数的估计值。 请注意,由于超时和中断可能在任何时间发生,因此估计仅用作实际服务员数量的上限。 此方法设计用于监视系统状态,而不是用于同步控制。- 参数
-
condition- 条件 - 结果
- 估计的等待线程数
- 异常
-
IllegalMonitorStateException- 如果未锁定此锁定 -
IllegalArgumentException- 如果给定条件与此锁定无关 -
NullPointerException- 如果条件为null
-
getWaitingThreads
protected Collection<Thread> getWaitingThreads(Condition condition)
返回一个集合,其中包含可能正在等待与此锁定关联的给定条件的那些线程。 因为实际的线程集可能在构造此结果时动态更改,所以返回的集合仅是尽力而为的估计。 返回集合的元素没有特定的顺序。 该方法旨在便于构建提供更广泛的状态监测设施的子类。- 参数
-
condition- 条件 - 结果
- 线程集合
- 异常
-
IllegalMonitorStateException- 如果未保持此锁定 -
IllegalArgumentException- 如果给定条件与此锁定无关 -
NullPointerException- 如果条件为null
-
-