ReentrantReadWriteLock.png
456af507-f0aa-4b02-afbd-1d137c239245.png
WriteLock
public void lock() {
sync.acquire(1);
}
tryAcquire
protected final boolean tryAcquire(int acquires) {
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)
// c不等0,w等于0,说明现在有人持有读锁,所以写锁拿不到
// 就算有人持有写锁,如果是别人的话,当然也不能拿到写锁
if (w == 0 || current != getExclusiveOwnerThread())
return false;
// 到这里,说明当前线程持有锁
// 重入写锁计数累加不能超过阈值,否则报错
if (w + exclusiveCount(acquires) > MAX_COUNT)
throw new Error("Maximum lock count exceeded");
// Reentrant acquire
// 设置state的重入计数
setState(c + acquires);
return true;
}
// 如果state等于0,说明现在还没有人持有任何锁
// 看是否按照公平原则来依次获取写锁,如果不是最早的waiter,那么会return
// 如果非公平模式,那么会尝试设置写锁计数,成功的话,绑定当前线程
// 否则返回
if (writerShouldBlock() ||
!compareAndSetState(c, c + acquires))
return false;
setExclusiveOwnerThread(current);
return true;
}
tryRelease
protected final boolean tryRelease(int releases) {
// 首先释放锁的前提是当前线程是持有人
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
int nextc = getState() - releases;
// 计算当前持有人释放的锁计数是否归零,归零才叫完全释放,否则只是重入锁自减
boolean free = exclusiveCount(nextc) == 0;
if (free)
setExclusiveOwnerThread(null);
setState(nextc);
return free;
}
tryWriteLock
final boolean tryWriteLock() {
Thread current = Thread.currentThread();
int c = getState();
if (c != 0) {
int w = exclusiveCount(c);
// c不等0,w等于0,说明现在有人持有读锁,所以写锁拿不到
// 就算有人持有写锁,如果是别人的话,当然也不能拿到写锁
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;
}
ReadLock
tryReadLock
final boolean tryReadLock() {
Thread current = Thread.currentThread();
// 自旋
for (;;) {
int c = getState();
// 如果有人持有写锁,且不是自己,那么读锁获取失败,返回false
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)) {
// 如果之前的计数为0,那么这个线程应该是第一个持有人,设置firstreader和HoldCount
if (r == 0) {
firstReader = current;
firstReaderHoldCount = 1;
// 直接firstReaderHoldCount累加
} else if (firstReader == current) {
firstReaderHoldCount++;
} else {
// cachedHoldCounter可以理解为最近一次读锁的持有人及计数
HoldCounter rh = cachedHoldCounter;
// 如果rh为空或持有人不是当前线程,那么去获取当前线程的HoldCounter
if (rh == null || rh.tid != getThreadId(current))
// 如果当前线程没有的话,会去init一个
// 或拿到持有人的HoldCounter
cachedHoldCounter = rh = readHolds.get();
else if (rh.count == 0)
readHolds.set(rh);
// 计数累加
rh.count++;
}
// 成功拿到读锁,结束自旋
return true;
}
}
}
tryAcquireShared
protected final int tryAcquireShared(int unused) {
Thread current = Thread.currentThread();
int c = getState();
// 如果当前状态时被其他线程独占,返回-1
if (exclusiveCount(c) != 0 &&
getExclusiveOwnerThread() != current)
return -1;
// 拿到当前共享锁的数量
int r = sharedCount(c);
// readerShouldBlock返回false
// 1. 下一个等待的线程必须是自己 (公平锁)
// 2. 只要下一个等待的不是写锁,谁来都可以 (非公平锁)
// 总之是可以拿读锁的状态
if (!readerShouldBlock() &&
r < MAX_COUNT &&
// CAS只要修改成功,就拿到锁
compareAndSetState(c, c + SHARED_UNIT)) {
// 如果当前还没有人共享,设置firstReader以及firstReaderHoldCount
if (r == 0) {
firstReader = current;
firstReaderHoldCount = 1;
// 如果firstReader已经是当前线程,只需要累加firstReaderHoldCount,记录重入数
} else if (firstReader == current) {
firstReaderHoldCount++;
} else {
HoldCounter rh = cachedHoldCounter;
// 如果rh为空或持有人不是当前线程,那么去获取当前线程的HoldCounter
if (rh == null || rh.tid != getThreadId(current))
// 如果当前线程没有的话,会去init一个
// 或拿到持有人的HoldCounter
cachedHoldCounter = rh = readHolds.get();
else if (rh.count == 0)
readHolds.set(rh);
// 自增当前线程的共享锁数目
rh.count++;
}
// 成功拿到锁,返回
return 1;
}
// 如果上面的步骤还没有拿到锁,那么进入自旋模式
return fullTryAcquireShared(current);
}
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();
// 如果当前有其他人持有写锁,那么返回-1,进入等待队列
// 那么有种情况是,正好是当前线程持有写锁,那么直接去下面执行锁降级
if (exclusiveCount(c) != 0) {
if (getExclusiveOwnerThread() != current)
return -1;
// else we hold the exclusive lock; blocking here
// would cause deadlock.
// 进到这里,说明当前没有人持有写锁,但是因为下面的原因导致获取读锁应该等待
// 1. 下个等待的线程不是自己 (公平锁)
// 2. 下一个等待的线程需要的写锁,非公平模式下写锁优先 (非公平锁)
} else if (readerShouldBlock()) {
// Make sure we're not acquiring read lock reentrantly
// 应该是个优化,如果发现读锁列表中跟firstReader匹配
// 说明是个重入读锁,直接去下面去累加重入计数
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");
// CAS获取读锁,并做记录
if (compareAndSetState(c, c + SHARED_UNIT)) {
// 如果读锁为0,那么记录下firstReader和HoldCount
if (sharedCount(c) == 0) {
firstReader = current;
firstReaderHoldCount = 1;
// 如果firstReader已经是当前线程,只需要累加firstReaderHoldCount,记录重入数
} else if (firstReader == current) {
firstReaderHoldCount++;
} else {
// 设置当前线程为cachedHoldCounter
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;
}
}
}
tryReleaseShared
protected final boolean tryReleaseShared(int unused) {
Thread current = Thread.currentThread();
// 看是否是首个读锁持有人,归零或自减重入计数
if (firstReader == current) {
// 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();
if (count <= 0)
throw unmatchedUnlockException();
}
--rh.count;
}
// 自旋
for (;;) {
int c = getState();
int nextc = c - SHARED_UNIT;
// 总读锁计数要减一
if (compareAndSetState(c, nextc))
// 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;
}
}
FairSync
writerShouldBlock&readerShouldBlock
public final boolean hasQueuedPredecessors() {
// The correctness of this depends on head being initialized
// before tail and on head.next being accurate if the current
// thread is first in queue.
Node t = tail; // Read fields in reverse initialization order
Node h = head;
Node s;
// true.
// 没有等待线程
// 有,但不是当前线程
// false
// 有,且是当前线程
// 而公平原则下,不像非公平那样写锁优先的逻辑,只是看队列的顺序,轮到谁了,谁来拿锁。
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}
NonfairSync
writerShouldBlock
final boolean writerShouldBlock() {
// 非公平下写锁是可以插队的,只要你够幸运
return false; // writers can always barge
}
readerShouldBlock
final boolean apparentlyFirstQueuedIsExclusive() {
Node h, s;
// true
// 有等待列表,且最早的等待的线程不是为了读锁,且thread不为空
// 换句话说,读锁是否需要等待得看后面等待的是不是写锁,如果是,写锁优先。
return (h = head) != null &&
(s = h.next) != null &&
!s.isShared() &&
s.thread != null;
}