ReentrantReadWriteLock 源码查看
其实也可以看 API 的,但我觉得看 API 没自己一个个仔细看印象深刻
一、类的注释说明
/**
* An implementation of {@link ReadWriteLock} supporting similar
* semantics to {@link ReentrantLock}.
* <p>This class has the following properties:
* /
/**
* ReadWriteLock 的支持与实现与 ReentrantLock 语义类似,此类具有以下属性:
*/
/**
* <li><b>Acquisition order</b>
*
* <p>This class does not impose a reader or writer preference
* ordering for lock access. However, it does support an optional
* <em>fairness</em> policy.
* /
/**
* 这个类不会强加 读锁 或写锁来优化锁定顺序,但是,它确实支持可选的公平策略
*/
/* <dt><b><i>Non-fair mode (default)</i></b>
* <dd>When constructed as non-fair (the default), the order of entry
* to the read and write lock is unspecified, subject to reentrancy
* constraints. A nonfair lock that is continuously contended may
* indefinitely postpone one or more reader or writer threads, but
* will normally have higher throughput than a fair lock.
* /
/*
* 非公平模式下
* 当被构造为非公平时(默认),进入读写锁定的顺序是未指定的。持续竞争的非空格
* 锁可能无限期地推迟一个或多个读卡器或写入器线程,但通常具有比公平锁更高的
* 吞吐量
*/
/* <dt><b><i>Fair mode</i></b>
* <dd>When constructed as fair, threads contend for entry using an
* approximately arrival-order policy. When the currently held lock
* is released, either the longest-waiting single writer thread will
* be assigned the write lock, or if there is a group of reader threads
* waiting longer than all waiting writer threads, that group will be
* assigned the read lock.
* /
/*
* 公平锁
* 当被构造为一个公平锁时,线程使用近似到达顺序策略争夺进入,当释放当前持有
* 锁时,要么将为等待时间最长的单个写线程将会被分配写入锁定,要么如果有一组
* 读线程等待比所有等待写入线程更长,则该组将被分配读取锁定
*/
/* <p>A thread that tries to acquire a fair read lock (non-reentrantly)
* will block if either the write lock is held, or there is a waiting
* writer thread. The thread will not acquire the read lock until
* after the oldest currently waiting writer thread has acquired and
* released the write lock. Of course, if a waiting writer abandons
* its wait, leaving one or more reader threads as the longest waiters
* in the queue with the write lock free, then those readers will be
* assigned the read lock.
* /
/*
* 尝试获取一个公平读锁的线程(不可重入)将会阻塞,如果持有写锁或有一个等待写的线程
* 这个线程不会获取读锁直到最长等待写线程已经获取并且释放写锁之后。当然,如果一个
* 等待写抛弃它的等待,留下一个或多个读线程作为队列中最长等待,其中写锁空闲,那么
* 这些读取器将分配读取锁定
*/
/* <p>A thread that tries to acquire a fair write lock (non-reentrantly)
* will block unless both the read lock and write lock are free (which
* implies there are no waiting threads). (Note that the non-blocking
* {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods
* do not honor this fair setting and will immediately acquire the lock
* if it is possible, regardless of waiting threads.)
* <p>
* /
/*
* 一个尝试去获取公平锁的线程(非重入)将会阻塞直到读锁和写锁都被释放(这意味着没
* 有等待线程),(注意:非阻塞 ReadLock#tryLock()方法和 WriteLock#tryLock() 方
* 法不符合此公平的设置,如果可能,将立即获取锁,而不管等待线程 )
*/
/* <li><b>Reentrancy</b>
*
* <p>This lock allows both readers and writers to reacquire read or
* write locks in the style of a {@link ReentrantLock}. Non-reentrant
* readers are not allowed until all write locks held by the writing
* thread have been released.
* /
/*
* 重入
* 这锁允许读写用户再次获取读锁或写锁在Reentrancy 风格中,在释放写线程所拥
* 有的所有写锁之前,不允许非可重入读
*/
/* <p>Additionally, a writer can acquire the read lock, but not
* vice-versa. Among other applications, reentrancy can be useful
* when write locks are held during calls or callbacks to methods that
* perform reads under read locks. If a reader tries to acquire the
* write lock it will never succeed.
*/
/**
* 此外,写用户可以获取读锁,反之不能。在其它应用程序中,当在调用或回调对在读
* 锁定下执行读取的方法的过程中保持写锁定时,重新进入很有用。如果读用户尝试获
* 取写锁,它将永远不会成功
*/
/* <li><b>Lock downgrading</b>
* <p>Reentrancy also allows downgrading from the write lock to a read lock,
* by acquiring the write lock, then the read lock and then releasing the
* write lock. However, upgrading from a read lock to the write lock is
* <b>not</b> possible.
* /
/*
* 锁降级
* 通过写锁,重入还允许从写锁 降级到读锁,获取写锁,然后再加读锁,然后再释放写锁。
* 然而从读锁升级为写锁是不可行的
*/
/* <li><b>Interruption of lock acquisition</b>
* <p>The read lock and write lock both support interruption during lock
* acquisition.
*/
/**
* 中断锁获取
* 读锁和写锁在锁获取期间都支持中断
*/
/*
* <li><b>{@link Condition} support</b>
* <p>The write lock provides a {@link Condition} implementation that
* behaves in the same way, with respect to the write lock, as the
* {@link Condition} implementation provided by
* {@link ReentrantLock#newCondition} does for {@link ReentrantLock}.
* This {@link Condition} can, of course, only be used with the write lock.
*
* <p>The read lock does not support a {@link Condition} and
* {@code readLock().newCondition()} throws
* {@code UnsupportedOperationException}.
*/
/*
* 条件支持
* 这个写锁提供了一个条件(Condition) 实现 ,其行为以相同的方式,相对于写入锁定,为
* Condition 所提供的实施 ReentrantLock#newCondition 确实为 ReentrantLock。这个
* 条件(Condition) 当然只能怪用于写锁
* 读锁不支持条件(Condition) 并且readLock().newCondition() 会抛出
* UnsupportedOperationException
*/
/*
* <li><b>Instrumentation</b>
* <p>This class supports methods to determine whether locks
* are held or contended. These methods are designed for monitoring
* system state, not for synchronization control.
* </ul>
* /
/*
* Instrumentation(仪器仪表)
* 此类支持确定是持有锁还是争用锁的方法。这些方法设计用于监视系统的状态,而不
* 用于同步控制
*/
/* <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><b>Sample usages</b>. Here is a code sketch showing how to perform
* lock downgrading after updating a cache (exception handling is
* particularly tricky when handling multiple locks in a non-nested
* fashion):
* /
/*
* 示例用法: 这是一个代码草图,显示了在更新缓存后如何执行锁降级(以非嵌套方式处理多个锁时,
* 异常处理特别棘手)
*/
class CachedData {
Object data;
volatile boolean cacheValid;
final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
void processCachedData() {
rwl.readLock().lock();
if (!cacheValid) {
// Must release read lock before acquiring write lock
rwl.readLock().unlock();
rwl.writeLock().lock();
try {
// Recheck state because another thread might have
// acquired write lock and changed state before we did.
if (!cacheValid) {
data = ...
cacheValid = true;
}
// Downgrade by acquiring read lock before releasing write lock
rwl.readLock().lock();
} finally {
rwl.writeLock().unlock(); // Unlock write, still hold read
}
}
try {
use(data);
} finally {
rwl.readLock().unlock();
}
}
}}</pre>
/* ReentrantReadWriteLocks can be used to improve concurrency in some
* uses of some kinds of Collections. This is typically worthwhile
* only when the collections are expected to be large, accessed by
* more reader threads than writer threads, and entail operations with
* overhead that outweighs synchronization overhead. For example, here
* is a class using a TreeMap that is expected to be large and
* concurrently accessed.
*/
/*
* ReentrantReadWriteLocks 可用于改进某些类型结合的某些用途中的并发性。这通常只有
* 当集合被预期为较大时才被认为是值得的,被比写线程更多的读线程访问,并且需要超出同步
* 开销的操作。例如,这里是一个使用 TreeMap 的类,该类将被大量并且同时访问:
*/
class RWDictionary {
private final Map<String, Data> m = new TreeMap<String, Data>();
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private final Lock r = rwl.readLock();
private final Lock w = rwl.writeLock();
public Data get(String key) {
r.lock();
try { return m.get(key); }
finally { r.unlock(); }
}
public String[] allKeys() {
r.lock();
try { return m.keySet().toArray(); }
finally { r.unlock(); }
}
public Data put(String key, Data value) {
w.lock();
try { return m.put(key, value); }
finally { w.unlock(); }
}
public void clear() {
w.lock();
try { m.clear(); }
finally { w.unlock(); }
}
}}
/* <p>This lock supports a maximum of 65535 recursive write locks
* and 65535 read locks. Attempts to exceed these limits result in
* {@link Error} throws from locking methods.
* /
/*
* 此锁最多支持 65535 个递归写锁和 65535 个读锁,尝试超过这些限制会导致
* 锁定方法抛出 error
*/
如下,可以看到 ReentrantReadWriteLock 的定义,它实现了 ReadWriteLock 和
Serializable 的接口。它里面的内部类有 : Sync 、 ReadLock 、 WriteLock 、
ThreadLocalHoldCounter、NonfairSync 和 FairSync
public class ReentrantReadWriteLock
implements ReadWriteLock, java.io.Serializable {
private static final long serialVersionUID = -6992448646407690164L;
/** Inner class providing readlock */
// 提供读锁的内部类
private final ReentrantReadWriteLock.ReadLock readerLock;
/** Inner class providing writelock */
// 提供写锁的内部类
private final ReentrantReadWriteLock.WriteLock writerLock;
/** Performs all synchronization mechanics */
// 执行所有同步机制
final Sync sync;
}
/**
* The number of reentrant read locks held by current thread.
* Initialized only in constructor and readObject.
* Removed whenever a thread's read hold count drops to 0.
*/
/**
* 当前线程持有的可重入读锁的数量。仅在构造函数和 readObject 中初始化
* 每当线程的读取保持计数降至 0 时将其删除
*/
private transient ThreadLocalHoldCounter readHolds;
/**
* The hold count of the last thread to successfully acquire
* readLock. This saves ThreadLocal lookup in the common case
* where the next thread to release is the last one to
* acquire. This is non-volatile since it is just used
* as a heuristic, and would be great for threads to cache.
*
* <p>Can outlive the Thread for which it is caching the read
* hold count, but avoids garbage retention by not retaining a
* reference to the Thread.
*
* <p>Accessed via a benign data race; relies on the memory
* model's final field and out-of-thin-air guarantees.
*/
/**
* 成功获取 readLock 的最后一个线程的保留计数。在下一个要释放的线程是最后
* 一个要获取的线程的情况下,这可以节省 ThreadLocal 查找。这是非易失性的,
* 因为它仅用作启发式方法,对于线程进行缓存非常有用。
* 可以使正在为其缓存读取保留计数的线程超时,但是可以通过不保留对线程的引用
* 来避免垃圾保留
* 良性的竞争访问,依赖于 final 的最终模型 和 out-of-thin-air 保障
*/
private transient HoldCounter cachedHoldCounter;
/**
* firstReader is the first thread to have acquired the read lock.
* firstReaderHoldCount is firstReader's hold count.
*
* <p>More precisely, firstReader is the unique thread that last
* changed the shared count from 0 to 1, and has not released the
* read lock since then; null if there is no such thread.
*
* <p>Cannot cause garbage retention unless the thread terminated
* without relinquishing its read locks, since tryReleaseShared
* sets it to null.
*
* <p>Accessed via a benign data race; relies on the memory
* model's out-of-thin-air guarantees for references.
*
* <p>This allows tracking of read holds for uncontended read
* locks to be very cheap.
*/
/**
* firstReader 是获取读锁的第一个线程,firstReaderHoldCount 是firstReader的持有数量
*
* 更确切的说 firstReader 是上次将共享计数从 0 更改为 1的唯一线程,此后未释放读取锁;如
* 果没有这样的线程,则返回 null
* 除非线程在不放弃读锁的情况下终止,否则不会导致垃圾保留,因为 tryReleaseShared 将其设置
* 为 null
* 通过良性数据竞争访问,依赖于内存模型的 out-of-thin-air 作为参考
* 这使得跟踪无竞争读取锁的读取保持非常便宜
*/
private transient Thread firstReader = null;
private transient int firstReaderHoldCount;
Ⅰ、Sync 类
Sync 类的定义: 抽象类,继承 AbstractQueuedSynchronizer
/**
* Synchronization implementation for ReentrantReadWriteLock.
* Subclassed into fair and nonfair versions.
*/
/**
* ReentrantReadWriteLock 的同步实现
* 分为公平与非公平版本
*/
abstract static class Sync extends AbstractQueuedSynchronizer
Sync 类的属性:
这里解释一下属性吧!
-
为什么 SHARED_SHIFT 为 16?
我们都知道 int 是 32 位,记录共享(读锁)占一半,记录独占(写锁)占一半,那么各自分得 16 -
<< 代表无符号左移,如: 二进制中 0001 无符号左移两位后为 0100
/*
* Read vs write count extraction constants and functions.
* Lock state is logically divided into two unsigned shorts:
* The lower one representing the exclusive (writer) lock hold count,
* and the upper the shared (reader) hold count.
*/
/**
* 读取与写入计数提取常量和函数
* 锁状态逻辑上被分成两个更小的部分:
* 这低位代表独占(写锁)持有数量
* 这高位代表共享(读锁)持有数量
*/
static final int SHARED_SHIFT = 16;
static final int SHARED_UNIT = (1 << SHARED_SHIFT);
static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1;
static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
/** Returns the number of shared holds represented in count */
// 返回以 count 表示的共享保留的数量
// 读锁计数,当前持有读锁的线程数
static int sharedCount(int c) { return c >>> SHARED_SHIFT; }
/** Returns the number of exclusive holds represented in count */
// 返回以 count 表示的独占保留的数量
// 写锁计数,也就是它的重入次数
static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
/**
* ThreadLocal subclass. Easiest to explicitly define for sake
* of deserialization mechanics.
*/
/**
* ThreadLocal 子类,为了进行反序列化,最容易明确定义
*/
static final class ThreadLocalHoldCounter
extends ThreadLocal<HoldCounter> {
public HoldCounter initialValue() {
return new HoldCounter();
}
}
/**
* A counter for per-thread read hold counts.
* Maintained as a ThreadLocal; cached in cachedHoldCounter
*/
/**
* 每个线程读取保持计数的计数器
* 维护 ThreadLocal ,缓存在 cachedHoldCounter 中
*/
static final class HoldCounter {
int count = 0;
// Use id, not reference, to avoid garbage retention
// 使用 id ,而不是引用来避免垃圾保留
final long tid = getThreadId(Thread.currentThread());
}
/*
* Acquires and releases use the same code for fair and
* nonfair locks, but differ in whether/how they allow barging
* when queues are non-empty.
*/
/**
* 获取释放使用相同的代码进行公平和非公平的锁,但在队列为非空时它们是否/如何
* 允许插入的方式
*/
/**
* Returns true if the current thread, when trying to acquire
* the read lock, and otherwise eligible to do so, should block
* because of policy for overtaking other waiting threads.
*/
/**
* 返回 true 如果当前线程尝试去获取读锁时(是否有资格这么做),应该被阻塞
* 因为有超过其它等待线程的策略
*/
abstract boolean readerShouldBlock();
/**
* Returns true if the current thread, when trying to acquire
* the write lock, and otherwise eligible to do so, should block
* because of policy for overtaking other waiting threads.
*/
/*
* 返回 true 如果当前线程,当尝试去获取写锁并由资格这么做时,因该阻塞
* 因为有超越其它等待线程的策略
*/
abstract boolean writerShouldBlock();
/*
* Note that tryRelease and tryAcquire can be called by
* Conditions. So it is possible that their arguments contain
* both read and write holds that are all released during a
* condition wait and re-established in tryAcquire.
*/
/**
* 注意: tryRelease 和 tryAcquire 能通过 Conditions 调用,
* 因此,它们的参数可能包含读和写保留,它们在条件等待期间全部释放,并在
* tryAcquire 中重新建立
*/
protected final boolean tryRelease(int releases) {
if (!isHeldExclusively()) // 判断是否是独占(true 如果同步仅针对当前调用线程进行)
throw new IllegalMonitorStateException();
int nextc = getState() - releases; // 释放锁
boolean free = exclusiveCount(nextc) == 0; // 独占保留数是否为 0
if (free)
setExclusiveOwnerThread(null); // 状态值为0,代表此时已经没有锁了,将独占访问线程设置为 null
setState(nextc); // 设置状态
return free;
}
说实话,这段还没怎么看明白
protected final boolean tryAcquire(int acquires) {
/*
* Walkthrough:
* 1. If read count nonzero or write count nonzero
* and owner is a different thread, fail.
* 2. If count would saturate, fail. (This can only
* happen if count is already nonzero.)
* 3. Otherwise, this thread is eligible for lock if
* it is either a reentrant acquire or
* queue policy allows it. If so, update state
* and set owner.
*/
/*
* 1. 如果读取计数为非零或写入计数为非零,并且所有者是另一个线程,则失败
* 2. 如果计数饱和,则失败(只有在count已经不为零的情况下才可以发生)
* 3. 否则。如果该线程是可重入获取或策略允许的话,则有资格进行锁定。如果是
* 这样,请更新状态并设置所有者
*/
Thread current = Thread.currentThread(); // 获取当前线程对象
int c = getState(); // 获取状态值
int w = exclusiveCount(c); // 获取写锁持有数量
if (c != 0) { // 说明上锁了,具体是什么锁未知
// (Note: if c != 0 and w == 0 then shared count != 0)
if (w == 0 || current != getExclusiveOwnerThread())
return false; // 此时 c!= 0 且 w == 0,则已经上了读锁了
if (w + exclusiveCount(acquires) > MAX_COUNT)
throw new Error("Maximum lock count exceeded"); //独占已持有锁数量加此次上锁数量>MAX_COUNT,抛出错误
// Reentrant acquire
setState(c + acquires); // 重入,更新状态值
return true;
}
if (writerShouldBlock() ||
!compareAndSetState(c, c + acquires))
return false;
setExclusiveOwnerThread(current);
return true;
}
protected final boolean tryReleaseShared(int unused) {
Thread current = Thread.currentThread(); // 获取当前线程
if (firstReader == current) {
// 进入判断,代表当前线程加了读锁
// assert firstReaderHoldCount > 0;
if (firstReaderHoldCount == 1)
firstReader = null; //firstReaderHoldCount 为 1,释放后当前线程将不再持有读锁,所有要将firstReader置为空
else
firstReaderHoldCount--; //firstReaderHoldCount>1,重入过,此时不能将 firstReader置为空
} else {
HoldCounter rh = cachedHoldCounter; // 获取 readLock 的最后一个线程的保留计数对象
if (rh == null || rh.tid != getThreadId(current))
rh = readHolds.get(); // 重新获取到 ThreadLocal
int count = rh.count; // 获取线程计数
if (count <= 1) {
readHolds.remove(); //计数小于等于 1,释放锁后线程将不再持有锁,此时需要将线程从ThreadLocalMap移除
if (count <= 0) //注意为0也会抛出异常,此时代表根本就没有持有锁,无法执行释放锁操作
throw unmatchedUnlockException();
}
--rh.count; //当前线程的读锁计数减一
}
for (;;) { // 死循环
int c = getState(); // 获取状态值
int nextc = c - SHARED_UNIT; // 状态值 - 共享单元的值 = 独占单元的值,如: 0101(状态)-0100(共享) = 0001(独占)
if (compareAndSetState(c, nextc)) // CAS 设置值
// Releasing the read lock has no effect on readers,
// but it may allow waiting writers to proceed if
// both read and write locks are now free.
// 释放读锁对读取没有影响,但是如果现在读锁和写锁均已被释放,则
// 可能允许等待的写入器继续进行
return nextc == 0;
}
}
private IllegalMonitorStateException unmatchedUnlockException() {
return new IllegalMonitorStateException(
"attempt to unlock read lock, not locked by current thread");
}
protected final int tryAcquireShared(int unused) {
/*
* Walkthrough:
* 1. If write lock held by another thread, fail.
* 2. Otherwise, this thread is eligible for
* lock wrt state, so ask if it should block
* because of queue policy. If not, try
* to grant by CASing state and updating count.
* Note that step does not check for reentrant
* acquires, which is postponed to full version
* to avoid having to check hold count in
* the more typical non-reentrant case.
* 3. If step 2 fails either because thread
* apparently not eligible or CAS fails or count
* saturated, chain to version with full retry loop.
*/
/*
* 1. 如果另一个线程持有写锁,则失败
* 2. 除此之外,该线程符合锁 wrt 状态,因此请问是否由于队列策略而应该阻塞
* 如果不是,请尝试 CASing 状态授予许可并更新计数。注意:该步骤不检查
* 重入获取,这回推迟到完整版本(这里应该指的是子类),以避免在更典型的非重入
* 的情况下必须检查保留计数
* 3. 如果第 2 步失败,或则由于线程显然步符合条件,或则 CAS 失败或计数饱和
* 请使用完整循环链接到版本
*/
Thread current = Thread.currentThread(); // 获取当前线程对象
int c = getState(); // 获取状态值
if (exclusiveCount(c) != 0 &&
getExclusiveOwnerThread() != current)
return -1; // 写锁计数不为0,并且独占线程不是当前线程(就是被其它线程上了写锁),直接 return
int r = sharedCount(c); // 获取共享数量
if (!readerShouldBlock() &&
r < MAX_COUNT &&
compareAndSetState(c, c + SHARED_UNIT)) {
if (r == 0) {
//如果 r 等于0,表明此时并没有上锁(读锁,写锁可能有不过是当前线程上的写锁)
firstReader = current; // 第一次加读锁,将当前线程赋给 firstReader
firstReaderHoldCount = 1; // 并将 firstReaderHoldCount 值赋为 1
} else if (firstReader == current) {
firstReaderHoldCount++; // r!=0,firstReader是当前线程,表明重入,
} else {
HoldCounter rh = cachedHoldCounter; // 获取 rh 对象,
if (rh == null || rh.tid != getThreadId(current))
cachedHoldCounter = rh = readHolds.get();//rh对象为空或rh的tid和当前线程的tid不等,则从readHolds获取
else if (rh.count == 0)
readHolds.set(rh); // rh.count 为0,将rh放入readHolds(ThreadLocalHoldCounter)对象中
rh.count++; // rh的计数加1
}
return 1;
}
return fullTryAcquireShared(current);
}
/**
* Full version of acquire for reads, that handles CAS misses
* and reentrant reads not dealt with in tryAcquireShared.
*/
/**
* 完整版本的获取读取,可处理 tryAcquireShared 中未处理的 CAS 丢失
* 和 重入读取
*/
final int fullTryAcquireShared(Thread current) {
/*
* This code is in part redundant with that in
* tryAcquireShared but is simpler overall by not
* complicating tryAcquireShared with interactions between
* retries and lazily reading hold counts.
*/
/**
* 此代码与 tryAcquireShared 中的代码部分冗余,但总体上更简单,
* 因为不 tryAcquireShared 与重试和延迟读取保持计数之间的交互复杂化
*/
HoldCounter rh = null;
for (;;) { // 死循环
int c = getState(); // 获取状态值
if (exclusiveCount(c) != 0) { // 写锁数不为 0,说明加了写锁
if (getExclusiveOwnerThread() != current)
return -1; //此时加写锁的不是当前线程,直接返回
// else we hold the exclusive lock; blocking here
// would cause deadlock.
//否则我们将持有排他锁;在这里阻塞将导致死锁
} else if (readerShouldBlock()) {
// Make sure we're not acquiring read lock reentrantly
// 确保我们没有重新获取读锁
if (firstReader == current) { // 当前线程是第一个上读锁的线程
// assert firstReaderHoldCount > 0; //断言(assert)
} else {
if (rh == null) {
rh = cachedHoldCounter;
if (rh == null || rh.tid != getThreadId(current)) {
rh = readHolds.get();
if (rh.count == 0)
readHolds.remove();
}
}
if (rh.count == 0)
return -1;
}
}
if (sharedCount(c) == MAX_COUNT)
throw new Error("Maximum lock count exceeded"); //共享数量等于 MAX_COUNT,抛出错误
if (compareAndSetState(c, c + SHARED_UNIT)) { // CAS 设置 贡献单元值
if (sharedCount(c) == 0) {
// 共享数量为 0,此时代表当前线程是第一个上读锁的,
firstReader = current;
firstReaderHoldCount = 1;
} else if (firstReader == current) {
firstReaderHoldCount++; // 重入情况,
} else {
if (rh == null)
rh = cachedHoldCounter; // rh 为空,重新获取
if (rh == null || rh.tid != getThreadId(current))
rh = readHolds.get(); // 再次判断rh,再次获取rh
else if (rh.count == 0)
readHolds.set(rh); // 将 rh 放入readHolds(ThreadLocalHoldCounter),本质上是 ThreadLocal
rh.count++;
cachedHoldCounter = rh; // cache for release 缓存发布
}
return 1;
}
}
}
/**
* Performs tryLock for write, enabling barging in both modes.
* This is identical in effect to tryAcquire except for lack
* of calls to writerShouldBlock.
*/
/**
* 执行 tryLock 进行写操作,从而在两种模式下都启用插入功能。除了缺少对
* writerShouldBlock的调用之外,这与 tryAcquire 效果相同
*/
final boolean tryWriteLock() {
Thread current = Thread.currentThread(); // 获取当前线程
int c = getState(); // 获取状态
if (c != 0) { // c 不为0 时,进入if代码块,此时说明被加锁了,是读锁还是写锁无法确定
int w = exclusiveCount(c); // 获取写锁的数量
if (w == 0 || current != getExclusiveOwnerThread())
return false; // 此时代表加了读锁,无法加写锁,所以直接返回
if (w == MAX_COUNT)
throw new Error("Maximum lock count exceeded");
}
if (!compareAndSetState(c, c + 1)) //加写锁
return false;
setExclusiveOwnerThread(current); // 将独占设置为当前线程(额,表述总感觉怪怪的)
return true;
}
/**
* Performs tryLock for read, enabling barging in both modes.
* This is identical in effect to tryAcquireShared except for
* lack of calls to readerShouldBlock.
*/
/**
* 对 tryLock 进行读取,从而在两种模式下都可以进行插入。除了缺少对
* readerShouldBlock 的调用外,这与 tryAcquireShared 的作用相同
*/
final boolean tryReadLock() {
Thread current = Thread.currentThread(); // 获取当前线程
for (;;) {
int c = getState(); // 获取状态
if (exclusiveCount(c) != 0 &&
getExclusiveOwnerThread() != current)
return false; // 已经加了写锁,并且加锁的线程不是当前线程,所以当前线程无法加读锁直接返回
int r = sharedCount(c); // 获取读锁数量
if (r == MAX_COUNT) //
throw new Error("Maximum lock count exceeded");
if (compareAndSetState(c, c + SHARED_UNIT)) { // 加读锁
if (r == 0) {
firstReader = current; // 第一次加读锁,将 firstReader 设置为 当前线程
firstReaderHoldCount = 1; // 将 firstReaderHoldCount 设置为 1
} else if (firstReader == current) {
firstReaderHoldCount++; // 重入情况
} else {
// 进入这里代表加读锁,但不是当前线程加的读锁
HoldCounter rh = cachedHoldCounter;
if (rh == null || rh.tid != getThreadId(current))
cachedHoldCounter = rh = readHolds.get();
else if (rh.count == 0)
readHolds.set(rh);
rh.count++;
}
return true;
}
}
}
protected final boolean isHeldExclusively() {
// While we must in general read state before owner,
// we don't need to do so to check if current thread is owner
// 虽然我们必须在拥有者之前先以一般状态读取state , 但我们
// 不需要这样做就可以检查当前线程是否为拥有者
return getExclusiveOwnerThread() == Thread.currentThread();
}
// Methods relayed to outer class
// 与外部类有关的方法
final ConditionObject newCondition() {
return new ConditionObject();
}
final Thread getOwner() {
// Must read state before owner to ensure memory consistency
// 必须在拥有者之前读取状态,以确保内存一致性
return ((exclusiveCount(getState()) == 0) ?
null :
getExclusiveOwnerThread());
}
final int getReadHoldCount() {
if (getReadLockCount() == 0)
return 0; // 没有上读锁,直接返回 0
Thread current = Thread.currentThread(); // 获取当前线程对象
if (firstReader == current)
return firstReaderHoldCount; // 如果firstReader等于当前线程对象,返回firstReaderHoldCount
HoldCounter rh = cachedHoldCounter;
if (rh != null && rh.tid == getThreadId(current))
return rh.count;
int count = readHolds.get().count;
if (count == 0) readHolds.remove();
return count;
}
/**
* Reconstitutes the instance from a stream (that is, deserializes it).
* 从流中重构实例(即反序列化它)
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
readHolds = new ThreadLocalHoldCounter();
setState(0); // reset to unlocked state
}
Ⅱ、NonfairSync
final boolean writerShouldBlock() {
return false; // writers can always barge 写应该总是 barge
}
final boolean readerShouldBlock() {
/* As a heuristic to avoid indefinite writer starvation,
* block if the thread that momentarily appears to be head
* of queue, if one exists, is a waiting writer. This is
* only a probabilistic effect since a new reader will not
* block if there is a waiting writer behind other enabled
* readers that have not yet drained from the queue.
*/
/**
* 作为一种避免无限期地饿死 写锁 的试探法,如果暂时看起来是队列
* 头的线程(如果存在的化)阻塞,则等待该 写锁.这是一种概率效应,因为
* 如果在其它启用的 读锁后面 没有等待中写锁还没有从队列中耗尽,那么
* 新的读锁不会阻塞
*/
return apparentlyFirstQueuedIsExclusive();
}
Ⅲ、FairSync
都是调用 hasQueuedPredecessors 方法
final boolean writerShouldBlock() {
return hasQueuedPredecessors();
}
final boolean readerShouldBlock() {
return hasQueuedPredecessors();
}
Ⅳ、ReadLock
ReadLock 实现了 Lock 和 java.io.Serializable 接口,并持有 Sync 对象
/**
* The lock returned by method {@link ReentrantReadWriteLock#readLock}.
* 方法 readLock 返回的锁
*/
public static class ReadLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = -5992448646407690164L;
private final Sync sync;
}
/**
* Constructor for use by subclasses
*
* @param lock the outer lock object
* @throws NullPointerException if the lock is null
*/
/**
* 子类使用的构造方法
* 参数 lock 外锁对象
*/
protected ReadLock(ReentrantReadWriteLock lock) {
sync = lock.sync;
}
/**
* Acquires the read lock.
*
* <p>Acquires the read lock if the write lock is not held by
* another thread and returns immediately.
*
* <p>If the write lock is held by another thread then
* the current thread becomes disabled for thread scheduling
* purposes and lies dormant until the read lock has been acquired.
*/
/**
* 获取读锁
* 获取读锁,如果没被其它线程上死锁,并且立即返回
* 如果写锁由另一个线程持有,则出于线程调度目的,当前线程将被禁用,并出于休眠状态
* 直到获取读锁为止
*/
public void lock() {
sync.acquireShared(1);
}
/**
* Acquires the read lock unless the current thread is
* {@linkplain Thread#interrupt interrupted}.
*
* <p>Acquires the read lock if the write lock is not held
* by another thread and returns immediately.
*
* <p>If the write 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 read lock is acquired by the current thread; or
*
* <li>Some other thread {@linkplain Thread#interrupt interrupts}
* the current thread.
*
* </ul>
*
* <p>If the current thread:
*
* <ul>
*
* <li>has its interrupted status set on entry to this method; or
*
* <li>is {@linkplain Thread#interrupt interrupted} while
* acquiring the read 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
*/
/**
* 获取读锁,除非当前线程为 打断
* 获取读锁,如果其它线程没有上写锁并立即返回
* 如果写锁被其它线程持有,然后当前线程出于线程调度目的而被禁用,并且处于休眠
* 状态直到发生两件事之一:
* 1. 读锁被当前线程获取
* 2. 其它线程打断当前线程
* 如果当前线程:
* 1. 在进入此方法时已设置其中断状态
* 2. 当获取读锁时被打断
* 然后 InterruptedException 将会被抛出,当前线程的打断状态被清除
* 在此实现中,由于此方法是显示的中断点,优先于对中断的响应,而不是正常
* 或可重入的锁获取
*/
public void lockInterruptibly() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
/**
* Acquires the read lock only if the write lock is not held by
* another thread at the time of invocation.
*
* <p>Acquires the read lock if the write lock is not held by
* another thread and returns immediately with the value
* {@code true}. Even when this lock has been set to use a
* fair ordering policy, a call to {@code tryLock()}
* <em>will</em> immediately acquire the read lock if it is
* available, whether or not other threads are currently
* waiting for the read 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 write lock is held by another thread then
* this method will return immediately with the value
* {@code false}.
*
* @return {@code true} if the read lock was acquired
*/
/**
* 仅当调用时,另一个线程未持有写锁时才能获取读锁
* 如果写锁未被另一个线程持有,则获取读锁,并立即返回值 true,即使将此锁设置
* 未使用公平的排序策略,无论当前是否正在等待其它线程,对 tryLock 的调用都会
* 立即获取读取锁(如果有)。用于读取锁定。它的 barging 行为在某些环境下能被用
* 到,即使破坏了它的公平性。如果要遵循此锁的公平性设置,请使用几乎等效的
* tryLock(0, TimeUnit.SECONDS)方法,而且它还会检测到中断
*/
public boolean tryLock() {
return sync.tryReadLock();
}
/**
* Acquires the read lock if the write lock is not held by
* another thread within the given waiting time and the
* current thread has not been {@linkplain Thread#interrupt
* interrupted}.
*
* <p>Acquires the read lock if the write lock is not held by
* another thread and returns immediately with the value
* {@code true}. 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 {@code tryLock} that does
* permit barging on a fair lock then combine the timed and
* un-timed forms together:
*
* <pre> {@code
* if (lock.tryLock() ||
* lock.tryLock(timeout, unit)) {
* ...
* }}</pre>
*
* <p>If the write 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 read lock is acquired by the current thread; or
*
* <li>Some other thread {@linkplain Thread#interrupt interrupts}
* the current thread; or
*
* <li>The specified waiting time elapses.
*
* </ul>
*
* <p>If the read lock is acquired then the value {@code true} is
* returned.
*
* <p>If the current thread:
*
* <ul>
*
* <li>has its interrupted status set on entry to this method; or
*
* <li>is {@linkplain Thread#interrupt interrupted} while
* acquiring the read 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
* {@code false} 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 read lock
* @param unit the time unit of the timeout argument
* @return {@code true} if the read lock was acquired
* @throws InterruptedException if the current thread is interrupted
* @throws NullPointerException if the time unit is null
*/
/**
* 如果在给定的等待时间内另一个线程未持有写锁,并且当前线程尚未打断,则获取读锁
* 获取读锁,如果写锁没有被其它线程持有,并且立即返回 true.如果已将此锁设置为使
* 用公平的排序策略,则如果任何其它线程正在等待该锁,则将不会获取可用的锁。
* 这与 trylock 方法相反,如果您想要定时的 tryLock 确实允许在公平锁上插入,
* 则将定时和非定时表单组合在一起:
* if (lock.tryLock() ||
* lock.tryLock(timeout, unit)) {
* ...
* }}
* 如果写锁被其它线程持有,则处于线程调度的目的,当前线程将被禁用,并处于休眠状态,
* 直到发生以下三种情况之一:
* 1.当前线程获取到了读锁
* 2.其它线程将当前线程打断
* 3.超过了指定的等待时间
* 如果获取了读锁,返回 true 值
* 如果当前线程:
* 1.在进入此方法时已设置其中断状态
* 2.当获取读锁时被中断
* 然后 InterruptedException 会被抛出,中断状态会被清除
* 如果指定时间过去,将返回 false,如果时间小于或等于 0 ,则该方法将不会等待
* 在此实现中,由于此方法是显示的中断点,因此优先于对中断的响应,而不是正常或
* 可重入的锁定获取,而是优先报告等待时间的流逝(这句不明白怎么翻译)
*/
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
/**
* Attempts to release this lock.
*
* <p>If the number of readers is now zero then the lock
* is made available for write lock attempts.
*/
/**
* 尝试去释放锁
* 如果现在 readers 的数量为 0,则这个锁可用于锁定尝试
*/
public void unlock() {
sync.releaseShared(1);
}
/**
* Returns a string identifying this lock, as well as its lock state.
* The state, in brackets, includes the String {@code "Read locks ="}
* followed by the number of held read locks.
*
* @return a string identifying this lock, as well as its lock state
*/
/**
* 返回标识此锁及其锁状态的字符串
* 括号中的状态包括字符串 locks,后跟持有的读取锁的数量
*/
public String toString() {
int r = sync.getReadLockCount();
return super.toString() +
"[Read locks = " + r + "]";
}
Ⅴ、WriteLock
/**
* Constructor for use by subclasses
*
* @param lock the outer lock object
* @throws NullPointerException if the lock is null
*/
/**
* 使用子类构造器
* 参数 lock 外部锁对象
* 抛出 NullPointerException 如果lock 为 null
*/
protected WriteLock(ReentrantReadWriteLock lock) {
sync = lock.sync;
}
/**
* Acquires the write lock.
*
* <p>Acquires the write lock if neither the read nor write lock
* are held by another thread
* and returns immediately, setting the write lock hold count to
* one.
*
* <p>If the current thread already holds the write 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 write lock has been acquired, at which
* time the write lock hold count is set to one.
*/
/**
* 获取写锁
* 获取写锁,如果其它线程即不持有读锁,也不持有写锁,立即返回并设置写锁
* 持有数量为 1
* 如果当前线程已经持有写锁,然后该持有数量加 1 并且方法立即返回
* 如果锁已经被其它线程锁持有,则当前线程将被禁用并处于休眠状态因为线程
* 调度目的,直到获取写锁为止,这时写锁计数设置为 1
*/
public void lock() {
sync.acquire(1);
}
/**
* Acquires the write lock unless the current thread is
* {@linkplain Thread#interrupt interrupted}.
*
* <p>Acquires the write lock if neither the read nor write lock
* are held by another thread
* and returns immediately, setting the write 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 write lock is acquired by the current thread; or
*
* <li>Some other thread {@linkplain Thread#interrupt interrupts}
* the current thread.
*
* </ul>
*
* <p>If the write 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 {@linkplain Thread#interrupt interrupted} while
* acquiring the write 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
*/
/**
* 获取写锁除非当前线程被打断
* 获取写锁如果其它线程并不持有读锁和写锁,并且立即返回 true,设置写锁数量为 1
* 如果当前线程已经持有这个锁,则持有数量加 1 ,并且方法立即返回
* 如果锁被其它线程持有,当前线程将被禁用并处于休眠状态因为线程调度,直到下面两件
* 事之一发生:
* 1. 这个写锁被当前线程获取
* 2. 其它线程打断当前线程
* 如果写锁被当前线程获取,则锁持有数量设置为 1
* 如果当前线程:
* 在进入此方法时已设置其中断状态
* 当获取写锁时被打断
* 则抛出异常 InterruptedException,并将打断状态清除
* 在这个实现中,由于此方法是显示的中断点,因此优先考虑对中断的响应,而不是正常或
* 可重入的锁获取
*/
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
/**
* Acquires the write lock only if it is not held by another thread
* at the time of invocation.
*
* <p>Acquires the write lock if neither the read nor write lock
* are held by another thread
* and returns immediately with the value {@code true},
* setting the write lock hold count to one. Even when this lock has
* been set to use a fair ordering policy, a call to
* {@code tryLock()} <em>will</em> immediately acquire the
* lock if it is available, whether or not other threads are
* currently waiting for the write 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
* {@code true}.
*
* <p>If the lock is held by another thread then this method
* will return immediately with the value {@code false}.
*
* @return {@code true} if the lock was free and was acquired
* by the current thread, or the write lock was already held
* by the current thread; and {@code false} otherwise.
*/
/**
* 获取写锁,仅当它没有被其它线程持有,在调用时
* 如果读锁和写锁均未被另一个线程持有,则获取写入锁定,并立即返回 true,将写锁
* 持有数量设置为 1,即使这个锁已经被设置为公平排序策略,无论当前是否正在等待其它
* 线程,调用 tryLock 方法都会立即获取该锁
* 即使破坏公平性,这种插入行为在默写去情况下也可能有用,如果要遵循此锁的公平性设置,
* 请使用 几乎等效的 tryLock(long, TimeUnit)(它会检测到中断)
*/
public boolean tryLock( ) {
return sync.tryWriteLock();
}
/**
* Acquires the write lock if it is not held by another thread
* within the given waiting time and the current thread has
* not been {@linkplain Thread#interrupt interrupted}.
*
* <p>Acquires the write lock if neither the read nor write lock
* are held by another thread
* and returns immediately with the value {@code true},
* setting the write 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 write lock. This is in contrast to the {@link
* #tryLock()} method. If you want a timed {@code tryLock}
* that does permit barging on a fair lock then combine the
* timed and un-timed forms together:
*
* <pre> {@code
* 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
* {@code true}.
*
* <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 write lock is acquired by the current thread; or
*
* <li>Some other thread {@linkplain Thread#interrupt interrupts}
* the current thread; or
*
* <li>The specified waiting time elapses
*
* </ul>
*
* <p>If the write lock is acquired then the value {@code true} is
* returned and the write 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 {@linkplain Thread#interrupt interrupted} while
* acquiring the write 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
* {@code false} 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 write lock
* @param unit the time unit of the timeout argument
*
* @return {@code true} if the lock was free and was acquired
* by the current thread, or the write lock was already held by the
* current thread; and {@code false} if the waiting time
* elapsed before the lock could be acquired.
*
* @throws InterruptedException if the current thread is interrupted
* @throws NullPointerException if the time unit is null
*/
/**
* 如果在给定的时间内,另一个线程未持有该锁,并且当前线程尚未被打断,则获取写锁
* 获取写锁如果其它线程读锁和写锁都不持有,并且立即返回 true,设置读锁持有数量为 1
* 如果这个锁已经被设置使用公平排序策略,如果任何其他线程正在等待写锁,则不会获取可用
* 的锁。这与 tryLock() 方法相反,如果您想要定时的 tryLock确实允许在公平锁上插入,
* 则将定时和非定时表单组合在一起:
* <pre> {@code
* if (lock.tryLock() ||
* lock.tryLock(timeout, unit)) {
* ...
* }}</pre>
* 如果当前线程已经持有这个锁,则持有数量加 1 并 立即返回
* 如果锁被其他线程锁持有,当前线程将被禁用休眠因为线程调度的原因
* 直到以下三件事的任一一件发生:
* 1. 写锁被当前线程获取
* 2. 当前线程被其他线程打断
* 3. 超出指定的等待时间
* 如果写锁被成功获取,则返回 true 并将写锁持有数量加 1
* 如果当前线程:
* 在执行这个方法之前已经被设置为打断状态
* 或当获取写锁时被打断,
* 则抛出 InterruptedException 并且当前线程的打断状态被清除
* 如果超出指定等待时间,则返回 false ,如果时间小于或等于 0,这个方法将
* 不会等待。
* 在此实现中,这个方法是一个显示的中断点,比正常或重入获取锁优先响应,
* 并且过渡报告等待时间流逝(这句怎么翻都感觉不对0.0)
*/
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, 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
*/
/**
* 尝试去释放锁
* 如果当前线程持有这个锁,则持有数量减少。如果持有数量当前为 0 ,则这个锁被释放,
* 如果当前线程不持有这个锁,则抛出 IllegalMonitorStateException
*/
public void unlock() {
sync.release(1);
}
/**
* 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 write lock is not held when any {@link
* Condition} method is called then an {@link
* IllegalMonitorStateException} is thrown. (Read locks are
* held independently of write locks, so are not checked or
* affected. However it is essentially always an error to
* invoke a condition waiting method when the current thread
* has also acquired read locks, since other threads that
* could unblock it will not be able to acquire the write
* lock.)
*
* <li>When the condition {@linkplain Condition#await() waiting}
* methods are called the write lock is released and, before
* they return, the write lock is reacquired and the lock hold
* count restored to what it was when the method was called.
*
* <li>If a thread is {@linkplain 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 sync.newCondition();
}
二、方法的实现与说明
/**
* Returns the thread that currently owns the write lock, or
* {@code null} if not owned. When this method is called by a
* thread that is not the owner, the return value reflects a
* best-effort approximation of current lock status. For example,
* the owner may be momentarily {@code null} 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 {@code null} if not owned
*/
/**
* 返回当前拥有写锁的线程,如果没有,则返回 null,当非所有者的线程调用此方法时,
* 返回值反映当前锁的状态的最大努力近似值,即使有线程试图获取锁,但所有者线程尚
* 未拥有,例如:所有者可能暂时为 null.设计此方法是为了便于构造提供更广泛的锁监
* 视功能的子类
*/
protected Thread getOwner() {
return sync.getOwner();
}
/**
* Queries the number of read locks held for this lock. This
* method is designed for use in monitoring system state, not for
* synchronization control.
* @return the number of read locks held
*/
/**
* 查询为此锁持有的读取锁的数量。此方法设计用于监视系统状态,而不用于
* 同步控制
* 返回 读锁持有数量
*/
public int getReadLockCount() {
return sync.getReadLockCount();
}
/**
* Queries if the write lock is held by any thread. This method is
* designed for use in monitoring system state, not for
* synchronization control.
*
* @return {@code true} if any thread holds the write lock and
* {@code false} otherwise
*/
/**
* 查询写锁是否由任何线程持有。此方法设计用于监视系统状态,而不用于
* 强制同步控制
*/
public boolean isWriteLocked() {
return sync.isWriteLocked();
}
/**
* Queries if the write lock is held by the current thread.
*
* @return {@code true} if the current thread holds the write lock and
* {@code false} otherwise
*/
/**
* 查询写锁是否呗当前线程持有
* 返回 true 如果当前线程持有写锁
*/
public boolean isWriteLockedByCurrentThread() {
return sync.isHeldExclusively();
}
/**
* Queries the number of reentrant write holds on this lock by the
* current thread. A writer thread has a hold on a lock for
* each lock action that is not matched by an unlock action.
*
* @return the number of holds on the write lock by the current thread,
* or zero if the write lock is not held by the current thread
*/
/**
* 查询当前线程对该锁持有的重入写入次数。对于未与解锁操作匹配的每个锁操作
* 编写器线程均拥有一个锁的保持
*/
public int getWriteHoldCount() {
return sync.getWriteHoldCount();
}
// 查询当前线程对该锁持有的可重入读取次数。对于与解锁操作不匹配的每个锁操作
// 读取器线程均具有锁定的保持状态
public int getReadHoldCount() {
return sync.getReadHoldCount();
}
/**
* Returns a collection containing threads that may be waiting to
* acquire the write 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 lock monitoring facilities.
*
* @return the collection of threads
*/
/**
* 返回一个包含可能正在等待获取获取写锁的线程集合。因为真实的集合可能会动态的
* 改变当构造这个集合的时候,返回集合只是尽力而为的估计,返回的集合元素没有特
* 定的顺序,设计此方法是为了便于构造提供更广泛的锁监视功能的子类
*/
protected Collection<Thread> getQueuedWriterThreads() {
return sync.getExclusiveQueuedThreads();
}
/**
* Returns a collection containing threads that may be waiting to
* acquire the read 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 lock monitoring facilities.
*
* @return the collection of threads
*/
/**
* 返回一个包含可能正在等待获取的线程的集合,因为实际的线程集在构造此结果时
* 可能会动态变化,所以返回的集合只是尽力而为的估计。返回的集合并没有特定顺
* 序,设计此方法是为了便于构造提供更广泛的锁监视功能的子类
*/
protected Collection<Thread> getQueuedReaderThreads() {
return sync.getSharedQueuedThreads();
}
/**
* Queries whether any threads are waiting to acquire the read or
* write lock. Note that because cancellations may occur at any
* time, a {@code true} return does not guarantee that any other
* thread will ever acquire a lock. This method is designed
* primarily for use in monitoring of the system state.
*
* @return {@code true} if there may be other threads waiting to
* acquire the lock
*/
/**
* 查询是否有任何线程正在等待获取读或写锁,注意:因为随时可能发生取消操作
* true 返回值不能保证任何其它线程将获得锁,此方法主要涉及用于建寺系统状态
*/
public final boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
/**
* Queries whether the given thread is waiting to acquire either
* the read or write lock. Note that because cancellations may
* occur at any time, a {@code true} return does not guarantee
* that this thread will ever acquire a lock. This method is
* designed primarily for use in monitoring of the system state.
*
* @param thread the thread
* @return {@code true} if the given thread is queued waiting for this lock
* @throws NullPointerException if the thread is null
*/
/**
* 查询给定的线程是否正在等待获取读取或写入锁定。请注意,因为取消可能随时发生,因此
* true 返回值不能保证此线程将获得锁,此方法主要用于设计监视系统状态
*/
public final boolean hasQueuedThread(Thread thread) {
return sync.isQueued(thread);
}
/**
* Returns a collection containing threads that may be waiting to
* acquire either the read or write 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<Thread> getQueuedThreads() {
return sync.getQueuedThreads();
}
/**
* Queries whether any threads are waiting on the given condition
* associated with the write lock. Note that because timeouts and
* interrupts may occur at any time, a {@code true} return does
* not guarantee that a future {@code signal} will awaken any
* threads. This method is designed primarily for use in
* monitoring of the system state.
*
* @param condition the condition
* @return {@code true} 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 the condition is null
*/
/**
* 查询是否有任何线程再等待与写锁关联的给定条件,注意:超时和打断可能在
* 任何时间内发生,一个 true 返回并不保证 future(将来) 会唤醒任何线程
* 这个方法主要被设计用于监控系统状态
*/
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 the write 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 the condition is 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 the write 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 the condition is null
*/
protected Collection<Thread> 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);
}