实现类ReentrantLock
二、“步入锁内部”——实现类ReentrantLock:
ReentrantLock不用解释就是指可重入的锁,多个线程可以并发对锁发出请求,但同一时刻只能有一个线程持有该锁。
/*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/licenses/publicdomain
*/
package edu.emory.mathcs.backport.java.util.concurrent.locks;
import java.util.*;
import edu.emory.mathcs.backport.java.util.concurrent.*;
import edu.emory.mathcs.backport.java.util.concurrent.helpers.*;
/**
* A reentrant mutual exclusion {@link Lock} with the same basic
* behavior and semantics as the implicit monitor lock accessed using
* <tt>synchronized</tt> methods and statements, but with extended
* capabilities.
*
* <p> A <tt>ReentrantLock</tt> is <em>owned</em> by the thread last
* successfully locking, but not yet unlocking it. A thread invoking
* <tt>lock</tt> will return, successfully acquiring the lock, when
* the lock is not owned by another thread. The method will return
* immediately if the current thread already owns the lock. This can
* be checked using methods {@link #isHeldByCurrentThread}, and {@link
* #getHoldCount}.
*
* <p> The constructor for this class accepts an optional
* <em>fairness</em> parameter. When set <tt>true</tt>, under
* contention, locks favor granting access to the longest-waiting
* thread. Otherwise this lock does not guarantee any particular
* access order. Programs using fair locks accessed by many threads
* may display lower overall throughput (i.e., are slower; often much
* slower) than those using the default setting, but have smaller
* variances in times to obtain locks and guarantee lack of
* starvation. Note however, that fairness of locks does not guarantee
* fairness of thread scheduling. Thus, one of many threads using a
* fair lock may obtain it multiple times in succession while other
* active threads are not progressing and not currently holding the
* lock.
* Also note that the untimed {@link #tryLock() tryLock} method does not
* honor the fairness setting. It will succeed if the lock
* is available even if other threads are waiting.
*
* <p> It is recommended practice to <em>always</em> immediately
* follow a call to <tt>lock</tt> with a <tt>try</tt> block, most
* typically in a before/after construction such as:
*
* <pre>
* class X {
* private final ReentrantLock lock = new ReentrantLock();
* // ...
*
* public void m() {
* lock.lock(); // block until condition holds
* try {
* // ... method body
* } finally {
* lock.unlock()
* }
* }
* }
* </pre>
*
* <p>In addition to implementing the {@link Lock} interface, this
* class defines methods <tt>isLocked</tt> and
* <tt>getLockQueueLength</tt>, as well as some associated
* <tt>protected</tt> access methods that may be useful for
* instrumentation and monitoring.
*
* <p> Serialization of this class behaves in the same way as built-in
* locks: a deserialized lock is in the unlocked state, regardless of
* its state when serialized.
*
* <p> This lock supports a maximum of 2147483648 recursive locks by
* the same thread.
*
* @since 1.5
* @author Doug Lea
*
*/
类的功能:
一个可重入的互斥锁仍然使用synchronized方法完成监视被访问锁的一些基本行为,但比synchronized的功能强大了。
类的详细描述:
一个ReentrantLock将被最近成功获得锁,而且还没有释放锁的线程所拥有。当锁没有被其它线程占有时,一个申请锁的线程将成功获得锁并返回。如果当前线程已经获得了锁,本方法将立即返回,开发者可以通过isHeldByCurrentThread和getHoldCount方法来检查此情况是否发生。
本类的构造器接收一个可选的参数:fairness(表示公平地分配锁)。当设置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接口,本类定义了isLocked、getLockQueueLength方法,就像一些protected方法一样对检测有所帮助。
本类的序列化与内建的锁的行为相同:一个被序列化的锁将处于解锁状态,不管它被序列化时的状态是怎样的。
本锁最大支持由同一个线程发起的2147483648个递归锁。
//本类实现了Lock接口、Serializable接口、LockInfo接口。
public class ReentrantLock implements Lock, java.io.Serializable,
CondVar.LockInfo {
private static final long serialVersionUID = 7373984872572414699L;
private final Impl impl;
//内部抽象类Impl定义开始
static abstract class Impl {
protected Thread owner_ = null;
protected int holds_ = 0;
protected Impl() {}
public abstract void lockInterruptibly() throws InterruptedException;
public boolean tryLock() {
Thread caller = Thread.currentThread();
//使用synchronized方法判断锁的持有者,并修改holds_计数
synchronized (this) {
if (caller == owner_) {
++holds_;
return true;
}
else if (owner_ == null) {
owner_ = caller;
holds_ = 1;
return true;
}
}
return false;
}
public abstract boolean tryLock(long nanos) throws InterruptedException;
public abstract void unlock();
public synchronized int getHoldCount() {
return isHeldByCurrentThread() ? holds_ : 0;
}
public synchronized boolean isHeldByCurrentThread() {
return Thread.currentThread() == owner_;
}
public synchronized boolean isLocked() {
return owner_ != null;
}
public abstract boolean isFair();
protected synchronized Thread getOwner() {
return owner_;
}
public boolean hasQueuedThreads() {
throw new UnsupportedOperationException("Use FAIR version");
}
public int getQueueLength() {
throw new UnsupportedOperationException("Use FAIR version");
}
public Collection getQueuedThreads() {
throw new UnsupportedOperationException("Use FAIR version");
}
public boolean isQueued(Thread thread) {
throw new UnsupportedOperationException("Use FAIR version");
}
}
Impl(公平锁)类的方法列表:
方法名 | 功能 | 备注 |
lockInterruptibly | 抽象方法定义 |
|
tryLock | 尝试获取锁 | 如果成功返回true,否则返回false |
tryLock(long nanos) | 抽象方法定义 |
|
unlock | 抽象方法定义 |
|
getHoldCount | 获得hold值 | 返回等待锁的线程数(hold值) |
isHeldByCurrentThread | 判断当前线程是否持有锁 |
|
isLocked | 判断锁是否被持有 |
|
isFair | 抽象方法定义 |
|
getOwner | 返回持有锁的线程对象 |
|
hasQueuedThreads | 判断等待对列中是否有线程(Impl不支持) | 抛出异常 |
getQueueLength | 返回等待对列的长度(Impl不支持) | 抛出异常 |
isQueued(Thread thread) | 判断线程是否存在在等待对列中(Impl不支持) | 抛出异常 |
由于Impl为公平锁的实现,且不使用等待对列管理等待线程,即不支持相应对列的方法。
在上表的方法中除了抽象方法外,其它方法均使用synchronized/notify方法保持线程同步。
/内部抽象类Impl定义结束
//内部抽象类NonfairImpl定义开始
//NonfairImpl继承Impl类,实现了Serializable接口。
static class NonfairImpl extends Impl implements java.io.Serializable {
NonfairImpl() {}
//可中断的lock
public void lockInterruptibly() throws InterruptedException {
//如果被其它线程中断,则抛出异常
if (Thread.interrupted()) throw new InterruptedException();
Thread caller = Thread.currentThread();
synchronized (this) {
if (caller == owner_)
++holds_;
else {
try {
//如果锁被占用,则等待直到锁被释放
while (owner_ != null) wait();
owner_ = caller;
holds_ = 1;
}
catch (InterruptedException ex) {
notify();
throw ex;
}
}
}
}
//带有超时的尝试获取锁
public boolean tryLock(long nanos) throws InterruptedException {
//如果被其它线程中断,则抛出异常
if (Thread.interrupted()) throw new InterruptedException();
Thread caller = Thread.currentThread();
synchronized (this) {
if (caller == owner_) {
++holds_;
return true;
}
else if (owner_ == null) {
owner_ = caller;
holds_ = 1;
return true;
}
else if (nanos <= 0)
return false;
else {
//计算超时时间deadline=当前时间的纳秒数+超时的纳秒数
long deadline = Utils.nanoTime() + nanos;
try {
for (; ; ) {
//等待nanos个纳秒。关于timedWait方法解释见下文
TimeUnit.NANOSECONDS.timedWait(this, nanos);
if (caller == owner_) {
++holds_;
return true;
}
else if (owner_ == null) {
owner_ = caller;
holds_ = 1;
return true;
}
else {
//更新nanos,如果nanos<=0,则超时
nanos = deadline - Utils.nanoTime();
if (nanos <= 0)
return false;
}
}
}
//如果等待过程中被中断,则抛出异常
catch (InterruptedException ex) {
notify();
throw ex;
}
}
}
}
TimeUnit类的timedWait方法解释(可参见TimeUntil.java和utils.java):
* @param obj the object to wait on * @param timeout the maximum time to wait.单位为纳秒 * @throws InterruptedException if interrupted while waiting. * @see Object#wait(long, int) */ public void timedWait(Object obj, long timeout) throws InterruptedException { if (timeout > 0) { //取得timeout的毫秒(舍弃余下的纳秒数) long ms = toMillis(timeout); //计算剩下的纳秒 int ns = excessNanos(timeout, ms); //obj等待(1000000*ms+ns)纳秒 obj.wait(ms, ns); } }
|
//解锁
public synchronized void unlock() {
//锁的持有者才能解锁
if (Thread.currentThread() != owner_)
throw new IllegalMonitorStateException("Not owner");
//修改holds_计数
if (--holds_ == 0) {
owner_ = null;
notify();
}
}
public final boolean isFair() {
return false;
}
}
NonfairImpl(不公平锁)类的方法列表:
方法名 | 功能 | 备注 |
lockInterruptibly | 可中断的lock |
|
tryLock | 尝试获取锁 | 如果成功返回true,否则返回false |
tryLock(long nanos) | 带有超时的尝试获取锁 | 如果成功返回true,否则返回false |
unlock | 解锁 |
|
isFair | 返回false |
|
NonfairImpl为不公平锁的实现。在上表的方法均使用synchronized/notify方法保持线程同步。
tryLock(long nanos)的超时判断和调用obj.wait实现线程的等待均是利用TimeUntil和utils类完成的。
//内部类NonfairImpl定义结束
//内部类FairImpl类定义开始
//FairImpl类继承Impl类,实现了等待对列的QueuedSync接口、Serializable接口
static class FairImpl extends Impl implements WaitQueue.QueuedSync,
java.io.Serializable {
//使用FIFO等待对列实现等待对列的
private final WaitQueue wq_ = new FIFOWaitQueue();
//重新检查——检查等待对列中的节点是否能获得锁
//如果不能获得,则将此节点插入等待对列
public synchronized boolean recheck(WaitQueue.WaitNode node) {
Thread caller = Thread.currentThread();
if (caller == owner_) {
++holds_;
return true;
}
else if (owner_ == null) {
owner_ = caller;
holds_ = 1;
return true;
}
wq_.insert(node);
return false;
}
//可中断的lock
public void lockInterruptibly() throws InterruptedException {
if (Thread.interrupted()) throw new InterruptedException();
Thread caller = Thread.currentThread();
synchronized (this) {
if (caller == owner_) {
++holds_;
return;
}
else if (owner_ == null) {
owner_ = caller;
holds_ = 1;
return;
}
}
//如果不能获得锁,则放入等待对列,直到获得锁或者被其它线程中断
WaitQueue.WaitNode n = new WaitQueue.WaitNode();
n.doWait(this);
//用断言判断是否获得锁
synchronized (this) {
assert owner_ == null;
owner_ = caller;
holds_ = 1;
}
}
//使用超时的尝试获取锁
public boolean tryLock(long nanos) throws InterruptedException {
if (Thread.interrupted()) throw new InterruptedException();
Thread caller = Thread.currentThread();
synchronized (this) {
if (caller == owner_) {
++holds_;
return true;
}
else if (owner_ == null) {
owner_ = caller;
holds_ = 1;
return true;
}
}
//如果不能获得锁,则放入等待对列,直到一定时间内获得锁或者被其它线程
//中断或超时
WaitQueue.WaitNode n = new WaitQueue.WaitNode();
if (n.doTimedWait(this, nanos)) {
synchronized (this) {
assert owner_ == null;
owner_ = caller;
holds_ = 1;
}
return true;
}
return false;
}
//解锁
public void unlock() {
boolean signal = false;
synchronized (this) {
if (Thread.currentThread() != owner_)
throw new IllegalMonitorStateException("Not owner");
if (--holds_ == 0) {
owner_ = null;
signal = true;
}
}
if (signal) {
// signal exactly one waiting thread at the head of the queue
//从FIFO等待对列中获取最先进入对列的节点,并发出信号唤醒此节点
while (true) {
WaitQueue.WaitNode n = wq_.extract();
if (n == null) return;
if (n.signal()) return;
}
}
}
public final boolean isFair() {
return true;
}
public synchronized boolean hasQueuedThreads() {
return wq_.hasNodes();
}
public synchronized int getQueueLength() {
return wq_.getLength();
}
public synchronized Collection getQueuedThreads() {
return wq_.getWaitingThreads();
}
public synchronized boolean isQueued(Thread thread) {
return wq_.isWaiting(thread);
}
}
WaitQueue.java类的doWait方法解释(可参见doWait.java):
/** * 等待对列中的节点等待 * @param QueuedSync接口 */ public synchronized void doWait(QueuedSync sync) throws InterruptedException { //调用QueuedSync接口的recheck方法 //在FairImpl类中调用就是调用FairImpl.recheck方法: //检查等待对列中的节点是否能获得锁 //如果不能获取,则将等待直到获得锁或者被其它线程中断 if (!sync.recheck(this)) { try { // while (waiting) wait(); } catch (InterruptedException ex) { if (waiting) { // no notification waiting = false; // invalidate for the signaller throw ex; } else { // thread was interrupted after it was notified Thread.currentThread().interrupt(); return; } } } }
/** * 发出信号唤醒本节点 */ public synchronized boolean signal() { boolean signalled = waiting; if (signalled) { waiting = false; notify(); } return signalled; } |
FairImpl(公平锁)类的方法列表:
方法名 | 功能 | 备注 |
recheck(WaitQueue.WaitNode node) | 重新检查 | 重新检查——检查等待对列中的节点是否能获得锁;如果不能获得,则将此节点插入等待对列 |
lockInterruptibly | 尝试获取锁 | 如果成功返回true,否则返回false;如果不能获得锁,则放入等待对列,直到获得锁或者被其它线程中断 |
tryLock(long nanos) | 使用超时的尝试获取锁 | 如果不能获得锁,则放入等待对列,直到一定时间内获得锁或者被其它线程中断或超时 |
unlock | 解锁 | 从FIFO等待对列中获取最先进入对列的节点,并发出信号唤醒此节点 |
isFair | 返回true |
|
hasQueuedThreads | 判断等待对列中是否有线程 |
|
getQueueLength | 返回等待对列的长度 |
|
getQueuedThreads | 以Collection的形式返回等待对列中的线程 |
|
isQueued(Thread thread) | 判断线程是否存在在等待对列中 |
|
FairImpl使用FIFO对列作为管理等待对列的方式,以达到公平的目的
//内部类FairImpl定义结束
/**
* Creates an instance of <tt>ReentrantLock</tt>.
* This is equivalent to using <tt>ReentrantLock(false)</tt>.
*/
public ReentrantLock() {
impl = new NonfairImpl();
}
方法功能:
ReentrantLock的构造方法:等同于使用ReentrantLock(false)构造方法。将建立的NonfairImpl类赋值给fairImpl和NonfairImpl类的父类impl抽象类。
/**
* Creates an instance of <tt>ReentrantLock</tt> with the
* given fairness policy.
* @param fair true if this lock will be fair; else false
*/
public ReentrantLock(boolean fair) {
impl = (fair)? (Impl)new FairImpl() : new NonfairImpl();
}
方法功能:
ReentrantLock构造方法,使用公平规则参数fair。
参数说明:
如果fair为true,则将建立的公平锁(FairImpl类对象)赋值给fairImpl和NonfairImpl类的父类impl抽象类,否则构造将建立的不公平锁(NonfairImpl类对象)赋值给fairImpl和NonfairImpl类的父类impl抽象类。
/**
* Acquires the lock.
*
* <p>Acquires the lock if it is not held by another thread and returns
* immediately, setting the lock hold count to one.
*
* <p>If the current thread
* already holds the lock then the hold count is incremented by one and
* the method returns immediately.
*
* <p>If the lock is held by another thread then the
* current thread becomes disabled for thread scheduling
* purposes and lies dormant until the lock has been acquired,
* at which time the lock hold count is set to one.
*/
public void lock() {
boolean wasInterrupted = false;
while (true) {
try {
impl.lockInterruptibly();
if (wasInterrupted) {
Thread.currentThread().interrupt();
}
return;
}
catch (InterruptedException e) {
wasInterrupted = true;
}
}
}
方法功能:
获取锁。通过调用impl. lockInterruptibly()实现。
详细描述:
如果锁没有被其它线程所占用,则立即获得锁并返回,设置锁的持有计数为1。如果锁被当前线程占用,则设置锁的持有计数+1后,本方法立即返回;如果锁被其它线程占有,当前线程被挂起直到获得被其它线程所占用的锁。如果当前线程在等待获取锁的过程中被其它线程中断,那么也将立即返回
/**
* Acquires the lock unless the current thread is
* {@link Thread#interrupt interrupted}.
*
* <p>Acquires the lock if it is not held by another thread and returns
* immediately, setting the lock hold count to one.
*
* <p>If the current thread already holds this lock then the hold count
* is incremented by one and the method returns immediately.
*
* <p>If the lock is held by another thread then the
* current thread becomes disabled for thread scheduling
* purposes and lies dormant until one of two things happens:
*
* <ul>
*
* <li>The lock is acquired by the current thread; or
*
* <li>Some other thread {@link Thread#interrupt interrupts} the current
* thread.
*
* </ul>
*
* <p>If the lock is acquired by the current thread then the lock hold
* count is set to one.
*
* <p>If the current thread:
*
* <ul>
*
* <li>has its interrupted status set on entry to this method; or
*
* <li>is {@link Thread#interrupt interrupted} while acquiring
* the lock,
*
* </ul>
*
* then {@link InterruptedException} is thrown and the current thread's
* interrupted status is cleared.
*
* <p>In this implementation, as this method is an explicit interruption
* point, preference is
* given to responding to the interrupt over normal or reentrant
* acquisition of the lock.
*
* @throws InterruptedException if the current thread is interrupted
*/
public void lockInterruptibly() throws InterruptedException {
impl.lockInterruptibly();
}
方法功能:
获取锁除非当前线程被中断。通过调用impl.lockInterruptibly()实现。
详细情况:
如果锁没有被其它线程所占用,则立即获得锁并返回,设置锁的持有计数为1。如果锁被当前线程占用,则设置锁的持有计数+1后,本方法立即返回;如果锁被其它线程占有,当前线程被挂起直到两件事发生:
1.获得被其它线程所占用的锁。
2.其它线程中断当前线程。
如果当前线程对本方法设置了中断状态集或者在正在获取锁时被中断,InterruptedException异常将被抛出,当前线程的中断状态将被清除。
异常情况:
当前线程被中断时抛出InterruptedException异常。
/**
* Acquires the lock only if it is not held by another thread at the time
* of invocation.
*
* <p>Acquires the lock if it is not held by another thread and
* returns immediately with the value <tt>true</tt>, setting the
* lock hold count to one. Even when this lock has been set to use a
* fair ordering policy, a call to <tt>tryLock()</tt> <em>will</em>
* immediately acquire the lock if it is available, whether or not
* other threads are currently waiting for the lock.
* This "barging" behavior can be useful in certain
* circumstances, even though it breaks fairness. If you want to honor
* the fairness setting for this lock, then use
* {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
* which is almost equivalent (it also detects interruption).
*
* <p> If the current thread
* already holds this lock then the hold count is incremented by one and
* the method returns <tt>true</tt>.
*
* <p>If the lock is held by another thread then this method will return
* immediately with the value <tt>false</tt>.
*
* @return <tt>true</tt> if the lock was free and was acquired by the
* current thread, or the lock was already held by the current thread; and
* <tt>false</tt> otherwise.
*/
public boolean tryLock() {
return impl.tryLock();
}
方法功能:
尝试获取锁。通过impl.tryLock()实现。
/**
* Acquires the lock if it is not held by another thread within the given
* waiting time and the current thread has not been
* {@link Thread#interrupt interrupted}.
*
* <p>Acquires the lock if it is not held by another thread and returns
* immediately with the value <tt>true</tt>, setting the lock hold count
* to one. If this lock has been set to use a fair ordering policy then
* an available lock <em>will not</em> be acquired if any other threads
* are waiting for the lock. This is in contrast to the {@link #tryLock()}
* method. If you want a timed <tt>tryLock</tt> that does permit barging on
* a fair lock then combine the timed and un-timed forms together:
*
* <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
* </pre>
*
* <p>If the current thread
* already holds this lock then the hold count is incremented by one and
* the method returns <tt>true</tt>.
*
* <p>If the lock is held by another thread then the
* current thread becomes disabled for thread scheduling
* purposes and lies dormant until one of three things happens:
*
* <ul>
*
* <li>The lock is acquired by the current thread; or
*
* <li>Some other thread {@link Thread#interrupt interrupts} the current
* thread; or
*
* <li>The specified waiting time elapses
*
* </ul>
*
* <p>If the lock is acquired then the value <tt>true</tt> is returned and
* the lock hold count is set to one.
*
* <p>If the current thread:
*
* <ul>
*
* <li>has its interrupted status set on entry to this method; or
*
* <li>is {@link Thread#interrupt interrupted} while acquiring
* the lock,
*
* </ul>
* then {@link InterruptedException} is thrown and the current thread's
* interrupted status is cleared.
*
* <p>If the specified waiting time elapses then the value <tt>false</tt>
* is returned.
* If the time is
* less than or equal to zero, the method will not wait at all.
*
* <p>In this implementation, as this method is an explicit interruption
* point, preference is
* given to responding to the interrupt over normal or reentrant
* acquisition of the lock, and over reporting the elapse of the waiting
* time.
*
* @param timeout the time to wait for the lock
* @param unit the time unit of the timeout argument
*
* @return <tt>true</tt> if the lock was free and was acquired by the
* current thread, or the lock was already held by the current thread; and
* <tt>false</tt> if the waiting time elapsed before the lock could be
* acquired.
*
* @throws InterruptedException if the current thread is interrupted
* @throws NullPointerException if unit is null
*
*/
public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
return impl.tryLock(unit.toNanos(timeout));
}
方法功能:
使用超时机制的尝试获取锁。通过impl.tryLock((unit.toNanos(timeout))实现。
/**
* Attempts to release this lock.
*
* <p>If the current thread is the
* holder of this lock then the hold count is decremented. If the
* hold count is now zero then the lock is released. If the
* current thread is not the holder of this lock then {@link
* IllegalMonitorStateException} is thrown.
* @throws IllegalMonitorStateException if the current thread does not
* hold this lock.
*/
public void unlock() {
impl.unlock();
}
方法功能:
释放锁。通过impl.unlock()实现。
/**
* Returns a {@link Condition} instance for use with this
* {@link Lock} instance.
*
* <p>The returned {@link Condition} instance supports the same
* usages as do the {@link Object} monitor methods ({@link
* Object#wait() wait}, {@link Object#notify notify}, and {@link
* Object#notifyAll notifyAll}) when used with the built-in
* monitor lock.
*
* <ul>
*
* <li>If this lock is not held when any of the {@link Condition}
* {@link Condition#await() waiting} or {@link Condition#signal
* signalling} methods are called, then an {@link
* IllegalMonitorStateException} is thrown.
*
* <li>When the condition {@link Condition#await() waiting}
* methods are called the lock is released and, before they
* return, the lock is reacquired and the lock hold count restored
* to what it was when the method was called.
*
* <li>If a thread is {@link Thread#interrupt interrupted} while
* waiting then the wait will terminate, an {@link
* InterruptedException} will be thrown, and the thread's
* interrupted status will be cleared.
*
* <li> Waiting threads are signalled in FIFO order
*
* <li>The ordering of lock reacquisition for threads returning
* from waiting methods is the same as for threads initially
* acquiring the lock, which is in the default case not specified,
* but for <em>fair</em> locks favors those threads that have been
* waiting the longest.
*
* </ul>
*
* @return the Condition object
*/
public Condition newCondition() {
return new CondVar(this);
}
方法功能:
返回锁的条件。
/**
* Queries the number of holds on this lock by the current thread.
*
* <p>A thread has a hold on a lock for each lock action that is not
* matched by an unlock action.
*
* <p>The hold count information is typically only used for testing and
* debugging purposes. For example, if a certain section of code should
* not be entered with the lock already held then we can assert that
* fact:
*
* <pre>
* class X {
* ReentrantLock lock = new ReentrantLock();
* // ...
* public void m() {
* assert lock.getHoldCount() == 0;
* lock.lock();
* try {
* // ... method body
* } finally {
* lock.unlock();
* }
* }
* }
* </pre>
*
* @return the number of holds on this lock by the current thread,
* or zero if this lock is not held by the current thread.
*/
public int getHoldCount() {
return impl.getHoldCount();
}
方法功能:
获取锁持有计数。调用impl.getHoldCount()实现。
详细描述:
本方法通常这样使用:
class X {
ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
assert lock.getHoldCount() == 0;
lock.lock();
try {
// ... method body
} finally {
lock.unlock();
}
}
}
/**
* Queries if this lock is held by the current thread.
*
* <p>Analogous to the {@link Thread#holdsLock} method for built-in
* monitor locks, this method is typically used for debugging and
* testing. For example, a method that should only be called while
* a lock is held can assert that this is the case:
*
* <pre>
* class X {
* ReentrantLock lock = new ReentrantLock();
* // ...
*
* public void m() {
* assert lock.isHeldByCurrentThread();
* // ... method body
* }
* }
* </pre>
*
* <p>It can also be used to ensure that a reentrant lock is used
* in a non-reentrant manner, for example:
*
* <pre>
* class X {
* ReentrantLock lock = new ReentrantLock();
* // ...
*
* public void m() {
* assert !lock.isHeldByCurrentThread();
* lock.lock();
* try {
* // ... method body
* } finally {
* lock.unlock();
* }
* }
* }
* </pre>
* @return <tt>true</tt> if current thread holds this lock and
* <tt>false</tt> otherwise.
*/
public boolean isHeldByCurrentThread() {
return impl.isHeldByCurrentThread();
}
方法功能:
返回当前线程是否持有锁。
/**
* Queries if this lock is held by any thread. This method is
* designed for use in monitoring of the system state,
* not for synchronization control.
* @return <tt>true</tt> if any thread holds this lock and
* <tt>false</tt> otherwise.
*/
public boolean isLocked() {
return impl.isLocked();
}
方法功能:
查询锁是否被占有。
/**
* Returns true if this lock has fairness set true.
* @return true if this lock has fairness set true.
*/
public final boolean isFair() {
return impl.isFair();
}
方法功能:
返回锁是否为公平锁。
/**
* Returns the thread that currently owns this lock, or
* <tt>null</tt> if not owned. Note that the owner may be
* momentarily <tt>null</tt> even if there are threads trying to
* acquire the lock but have not yet done so. This method is
* designed to facilitate construction of subclasses that provide
* more extensive lock monitoring facilities.
* @return the owner, or <tt>null</tt> if not owned.
*/
protected Thread getOwner() {
return impl.getOwner();
}
方法功能:
返回当前持有锁的线程。
/**
* Queries whether any threads are waiting to acquire this lock. Note that
* because cancellations may occur at any time, a <tt>true</tt>
* return does not guarantee that any other thread will ever
* acquire this lock. This method is designed primarily for use in
* monitoring of the system state.
*
* @return true if there may be other threads waiting to acquire
* the lock.
*/
public final boolean hasQueuedThreads() {
return impl.hasQueuedThreads();
}
方法功能:
返回等待对列中是否有线程在等待。
/**
* Queries whether the given thread is waiting to acquire this
* lock. Note that because cancellations may occur at any time, a
* <tt>true</tt> return does not guarantee that this thread
* will ever acquire this lock. This method is designed primarily for use
* in monitoring of the system state.
*
* @param thread the thread
* @return true if the given thread is queued waiting for this lock.
* @throws NullPointerException if thread is null
*/
public final boolean hasQueuedThread(Thread thread) {
return impl.isQueued(thread);
}
方法功能:
返回某个线程是否存在于等待对列。
/**
* Returns an estimate of the number of threads waiting to
* acquire this lock. The value is only an estimate because the number of
* threads may change dynamically while this method traverses
* internal data structures. This method is designed for use in
* monitoring of the system state, not for synchronization
* control.
* @return the estimated number of threads waiting for this lock
*/
public final int getQueueLength() {
return impl.getQueueLength();
}
方法功能:
返回等待对列的长度。
/**
* Returns a collection containing threads that may be waiting to
* acquire this lock. Because the actual set of threads may change
* dynamically while constructing this result, the returned
* collection is only a best-effort estimate. The elements of the
* returned collection are in no particular order. This method is
* designed to facilitate construction of subclasses that provide
* more extensive monitoring facilities.
* @return the collection of threads
*/
protected Collection getQueuedThreads() {
return impl.getQueuedThreads();
}
方法功能:
以Collection的方式返回等待对列中的所有线程。
// /**
// * Queries whether any threads are waiting on the given condition
// * associated with this lock. Note that because timeouts and
// * interrupts may occur at any time, a <tt>true</tt> return does
// * not guarantee that a future <tt>signal</tt> will awaken any
// * threads. This method is designed primarily for use in
// * monitoring of the system state.
// * @param condition the condition
// * @return <tt>true</tt> if there are any waiting threads.
// * @throws IllegalMonitorStateException if this lock
// * is not held
// * @throws IllegalArgumentException if the given condition is
// * not associated with this lock
// * @throws NullPointerException if condition null
// */
// public boolean hasWaiters(Condition condition) {
// if (condition == null)
// throw new NullPointerException();
// if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
// throw new IllegalArgumentException("not owner");
// return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
// }
// /**
// * Returns an estimate of the number of threads waiting on the
// * given condition associated with this lock. Note that because
// * timeouts and interrupts may occur at any time, the estimate
// * serves only as an upper bound on the actual number of waiters.
// * This method is designed for use in monitoring of the system
// * state, not for synchronization control.
// * @param condition the condition
// * @return the estimated number of waiting threads.
// * @throws IllegalMonitorStateException if this lock
// * is not held
// * @throws IllegalArgumentException if the given condition is
// * not associated with this lock
// * @throws NullPointerException if condition null
// */
// public int getWaitQueueLength(Condition condition) {
// if (condition == null)
// throw new NullPointerException();
// if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
// throw new IllegalArgumentException("not owner");
// return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
// }
// /**
// * Returns a collection containing those threads that may be
// * waiting on the given condition associated with this lock.
// * Because the actual set of threads may change dynamically while
// * constructing this result, the returned collection is only a
// * best-effort estimate. The elements of the returned collection
// * are in no particular order. This method is designed to
// * facilitate construction of subclasses that provide more
// * extensive condition monitoring facilities.
// * @param condition the condition
// * @return the collection of threads
// * @throws IllegalMonitorStateException if this lock
// * is not held
// * @throws IllegalArgumentException if the given condition is
// * not associated with this lock
// * @throws NullPointerException if condition null
// */
// protected Collection getWaitingThreads(Condition condition) {
// if (condition == null)
// throw new NullPointerException();
// if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
// throw new IllegalArgumentException("not owner");
// return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
// }
/**
* Returns a string identifying this lock, as well as its lock
* state. The state, in brackets, includes either the String
* "Unlocked" or the String "Locked by"
* followed by the {@link Thread#getName} of the owning thread.
* @return a string identifying this lock, as well as its lock state.
*/
public String toString() {
Thread owner = getOwner();
return super.toString() + ((owner == null) ?
"[Unlocked]" :
"[Locked by thread " + owner.getName() + "]");
}
}