- java.lang.Object
-
- java.util.concurrent.locks.ReentrantLock
-
- All Implemented Interfaces:
-
Serializable
,Lock
public class ReentrantLock extends Object implements Lock, Serializable
可重入互斥Lock
具有与使用synchronized
方法和语句访问的隐式监视锁相同的基本行为和语义,但具有扩展功能。A
ReentrantLock
由线程拥有 ,最后成功锁定,但尚未解锁。 调用lock
的线程将返回,当锁不是由另一个线程拥有时,成功获取锁。 如果当前线程已经拥有该锁,该方法将立即返回。 这可以使用方法isHeldByCurrentThread()
和getHoldCount()
进行检查。该类的构造函数接受可选的公平参数。 设置
true
,在争用的情况下,锁有利于授予对最长等待线程的访问权限。 否则,该锁不保证任何特定的访问顺序。 使用许多线程访问的公平锁的程序可能会比使用默认设置的整体吞吐量(即,更慢,通常要慢得多),但是具有更小的差异来获得锁定并保证缺乏饥饿。 但是请注意,锁的公平性不能保证线程调度的公平性。 因此,使用公平锁的许多线程之一可以连续获得多次,而其他活动线程不进行而不是当前持有锁。 另请注意,未定义的tryLock()
方法不符合公平性设置。 如果锁可用,即使其他线程正在等待,它也会成功。建议您务必立即致电
lock
与try
块,最典型的是在之前/之后施工,如: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
-
-
构造方法摘要
构造方法 Constructor 描述 ReentrantLock()
创建一个ReentrantLock
的实例。ReentrantLock(boolean fair)
使用给定的公平政策创建一个ReentrantLock
的实例。
-
方法摘要
所有方法 接口方法 具体的方法 Modifier and Type 方法 描述 int
getHoldCount()
查询当前线程对此锁的暂停数量。protected Thread
getOwner()
返回当前拥有此锁的线程,如果不拥有,则返回null
。protected Collection<Thread>
getQueuedThreads()
返回包含可能正在等待获取此锁的线程的集合。int
getQueueLength()
返回等待获取此锁的线程数的估计。protected Collection<Thread>
getWaitingThreads(Condition condition)
返回包含可能在与此锁相关联的给定条件下等待的线程的集合。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()
获取锁定,除非当前线程是 interrupted 。Condition
newCondition()
String
toString()
返回一个标识此锁的字符串以及其锁定状态。boolean
tryLock()
只有在调用时它不被另一个线程占用才能获取锁。boolean
tryLock(long timeout, TimeUnit unit)
如果在给定的等待时间内没有被另一个线程 占用 ,并且当前线程尚未被 interrupted采集锁定 。void
unlock()
尝试释放此锁。
-
-
-
方法详细信息
-
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
并且立即返回值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
与使用时)内置监视器锁定。- 如果在调用任何
Condition
waiting或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
如果这个锁的公平设置为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
- 条件为空
-
-