ReentrantReadWriteLock#WriteLock#lock
public void lock() {
sync.acquire(1); //尝试获取资源
}
ReentrantReadWriteLock#tryAcquire
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.
*/
Thread current = Thread.currentThread();
int c = getState(); //获取线程状态
int w = exclusiveCount(c); //计算低16位值
if (c != 0) {
// (Note: if c != 0 and w == 0 then shared count != 0)
if (w == 0 || current != getExclusiveOwnerThread()) //read 共享数量不为0
return false;
if (w + exclusiveCount(acquires) > MAX_COUNT) //最大为2的16次方-1 65535
throw new Error("Maximum lock count exceeded");
// Reentrant acquire
setState(c + acquires); //设置状态 +1
return true;
}
//c = 0 则表示没有读锁与写锁,cas尝试获取写锁
//writerShouldBlock : 公平锁判断是否为head的下一个继承者,如果有排队则直接返回
if (writerShouldBlock() ||
!compareAndSetState(c, c + acquires))
return false;
setExclusiveOwnerThread(current); //标明独占线程
return true;
}
ReentrantReadWriteLock#WriteLock#unlock
public void unlock() {
sync.release(1); //尝试释放资源
}
ReentrantReadWriteLock#tryRelease
protected final boolean tryRelease(int releases) {
if (!isHeldExclusively()) //判断是否为当前线程持有锁
throw new IllegalMonitorStateException();
int nextc = getState() - releases; //获取释放后的状态值
boolean free = exclusiveCount(nextc) == 0; //如果状态值为0 则表示锁已经完全释放
if (free)
setExclusiveOwnerThread(null);
setState(nextc);
return free; //释放return true 则唤醒一个节点操作
}
ReentrantReadWriteLock#ReadLock#lock
public void lock() {
sync.acquireShared(1); //尝试获取共享锁资源
}
AQS#acquireShared
public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0) //获取资源失败
doAcquireShared(arg); //加入同步队列后,再循环cas获取资源
}
ReentrantReadWriteLock#tryAcquireShared
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.
*/
Thread current = Thread.currentThread();
int c = getState(); //获取线程状态
if (exclusiveCount(c) != 0 && //排他锁状态信息 //已经含有写锁,且不是当前线程
getExclusiveOwnerThread() != current)
return -1;
int r = sharedCount(c); //共享锁状态信息
//获取读锁成功
if (!readerShouldBlock() &&
//非公平锁:apparentlyFirstQueuedIsExclusive 判断下一个队列是否为独占节点
//公平锁:判断是否下一个等待的节点是否为当前线程
r < MAX_COUNT && //数量为65535 2的16次方-1
compareAndSetState(c, c + SHARED_UNIT)) { //尝试获取共享资源
if (r == 0) { //写锁数量为0,则将当前线程设为队列头
firstReader = current;
firstReaderHoldCount = 1;
} else if (firstReader == current) { //重入数量+1
firstReaderHoldCount++;
} else {
HoldCounter rh = cachedHoldCounter;
if (rh == null || rh.tid != getThreadId(current))
cachedHoldCounter = rh = readHolds.get(); // theadLocal 子类 初始化 cachedHoldCounter
else if (rh.count == 0)
readHolds.set(rh);
rh.count++; //用threadlocal 管理每个线程的计数器
}
return 1;
}
//获取读锁失败,循环 cas 操作
return fullTryAcquireShared(current);
}
ReentrantReadWriteLock#fullTryAcquireShared
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.
*/
HoldCounter rh = null;
for (;;) {
int c = getState();
if (exclusiveCount(c) != 0) { //重复判断是否有写锁
if (getExclusiveOwnerThread() != current)
return -1;
// else we hold the exclusive lock; blocking here
// would cause deadlock.
} else if (readerShouldBlock()) { //需要blocking 直到能获取资源
// Make sure we're not acquiring read lock reentrantly
if (firstReader == current) {
// assert firstReaderHoldCount > 0;
} 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");
if (compareAndSetState(c, c + SHARED_UNIT)) { //重复获取操作
if (sharedCount(c) == 0) {
firstReader = current;
firstReaderHoldCount = 1;
} else if (firstReader == current) {
firstReaderHoldCount++;
} else {
if (rh == null)
rh = cachedHoldCounter;
if (rh == null || rh.tid != getThreadId(current))
rh = readHolds.get();
else if (rh.count == 0)
readHolds.set(rh);
rh.count++;
cachedHoldCounter = rh; // cache for release
}
return 1;
}
}
}
AQS#doAcquireShared
private void doAcquireShared(int arg) {
final Node node = addWaiter(Node.SHARED); //将share节点入队列
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head) { //队列中只有头节点能获取资源
int r = tryAcquireShared(arg); //尝试获取读锁资源
if (r >= 0) { //资源获取成功
setHeadAndPropagate(node, r); //设置为头节点,并尝试唤醒下一个共享节点
p.next = null; // help GC
if (interrupted) //判断中断
selfInterrupt();
failed = false;
return;
}
}
//清除cancel节点,后park等待signal
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
AQS#setHeadAndPropagate
private void setHeadAndPropagate(Node node, int propagate) {
Node h = head; // Record old head for check below
setHead(node);
/*
* Try to signal next queued node if:
* Propagation was indicated by caller,
* or was recorded (as h.waitStatus either before
* or after setHead) by a previous operation
* (note: this uses sign-check of waitStatus because
* PROPAGATE status may transition to SIGNAL.)
* and
* The next node is waiting in shared mode,
* or we don't know, because it appears null
*
* The conservatism in both of these checks may cause
* unnecessary wake-ups, but only when there are multiple
* racing acquires/releases, so most need signals now or soon
* anyway.
*/
if (propagate > 0 || h == null || h.waitStatus < 0 ||
(h = head) == null || h.waitStatus < 0) {
Node s = node.next;
if (s == null || s.isShared()) //如果下一个节点也是共享锁,则唤醒下一个节点
doReleaseShared();
}
}
ReentrantReadWriteLock#readlock#unlock
public void unlock() {
sync.releaseShared(1);
}
AQS#releaseShared
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) { //尝试释放资源 读锁全部释放后为true
doReleaseShared(); //唤醒后继节点
return true;
}
return false;
}
ReentrantReadWriteLock#tryReleaseShared
protected final boolean tryReleaseShared(int unused) {
Thread current = Thread.currentThread();
if (firstReader == current) { // 判断当前线程时否为第一个reader
// assert firstReaderHoldCount > 0;
if (firstReaderHoldCount == 1)
firstReader = null;
else
firstReaderHoldCount--;
} else {
HoldCounter rh = cachedHoldCounter;
if (rh == null || rh.tid != getThreadId(current))
rh = readHolds.get(); //获取当前线程的计数器
int count = rh.count;
if (count <= 1) {
readHolds.remove(); //< 1 则释放当前计数器
if (count <= 0)
throw unmatchedUnlockException();
}
--rh.count;
}
for (;;) {
int c = getState();
int nextc = c - SHARED_UNIT;
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; //读锁free
}
}
AQS#doReleaseShared
//释放共享锁,唤醒下一个节点
private void doReleaseShared() {
/*
* Ensure that a release propagates, even if there are other
* in-progress acquires/releases. This proceeds in the usual
* way of trying to unparkSuccessor of head if it needs
* signal. But if it does not, status is set to PROPAGATE to
* ensure that upon release, propagation continues.
* Additionally, we must loop in case a new node is added
* while we are doing this. Also, unlike other uses of
* unparkSuccessor, we need to know if CAS to reset status
* fails, if so rechecking.
*/
for (;;) {
Node h = head;
//最终状态 signal = 》0 = 》 PROPAGATE 经过一步0的操作时因为unparkSuccessor 中会有cas设置为0状态
if (h != null && h != tail) {
int ws = h.waitStatus; //获取头节点的状态
if (ws == Node.SIGNAL) { //如果节点的状态为唤醒,则置为0
if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0)) //失败则跳出循环重新开始
continue; // loop to recheck cases
unparkSuccessor(h); //唤醒下一个节点
} else if (ws == 0 &&
!compareAndSetWaitStatus(h, 0, Node.PROPAGATE)) //将节点设置为可传播
continue; // loop on failed CAS
}
//如果头节点被更换,即下一个节点被唤醒
if (h == head) // loop if head changed
break;
}
}