ReentrantReadWriteLock 可重入读写锁,内部维持了ReadLock和WriteLock,分为公平锁和非公平锁,由于读锁和写锁使用了同一个Sync对象,所以如果第一次获取锁失败,都会被放入同一个队列中。底层使用了AQS,state高16位表示共享锁-读锁,低16位表示独占锁-写锁。
cachedHoldCounter 记录了上一个读线程的重入count,避免频繁从ThreadLocal中读取,提升性能。
firstReader 记录第一个读线程,没有放入ThreadLocal,提升性能。
1. 如果一个线程持有了读锁,不能再持有写锁
2. 说明如果一个线程持有了写锁 可以再持有读锁
3. 锁可以降级(写锁->读锁) 不能升级(读锁->写锁),想要升级就得先释放读锁,然后获取写锁
源码
public class ReentrantReadWriteLock
implements ReadWriteLock, java.io.Serializable {
// 读锁 共享锁
private final ReentrantReadWriteLock.ReadLock readerLock;
// 写锁 独占锁
private final ReentrantReadWriteLock.WriteLock writerLock;
// 同步属性 AQS子类
final Sync sync;
// 构造方法 默认非公平锁
public ReentrantReadWriteLock() {
this(false);
}
public ReentrantReadWriteLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
readerLock = new ReadLock(this);
writerLock = new WriteLock(this);
}
public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; }
abstract static class Sync extends AbstractQueuedSynchronizer {
// 将state进行拆分 高16位表示共享锁 低16位表示独占锁
static final int SHARED_SHIFT = 16;
// 共享锁高16位 每次变更的最小单元
static final int SHARED_UNIT = (1 << SHARED_SHIFT);
// 各锁线程最大个数
static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1;
// 1右移16位-1 得到低16位都是1
static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
// 无符号右移16位 剩余高16位
static int sharedCount(int c) { return c >>> SHARED_SHIFT; }
// 与低16位都是1的数按位与 得到低16位
static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
static final class HoldCounter {
int count = 0;
// Use id, not reference, to avoid garbage retention
final long tid = getThreadId(Thread.currentThread());
}
...
// 重写AQS独占锁方法
protected final boolean tryRelease(int releases) {
// 当前线程是否持有独占锁
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
// 计算剩余state
int nextc = getState() - releases;
// 如果剩余写锁数量为0 表示释放了写锁
boolean free = exclusiveCount(nextc) == 0;
if (free)
setExclusiveOwnerThread(null);
setState(nextc); // 更新state
return free;
}
// 重写AQS独占锁方法
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)
if (w == 0 || current != getExclusiveOwnerThread()) // 拥有锁的线程不是当前线程
return false;
if (w + exclusiveCount(acquires) > MAX_COUNT) // 如果数量超过限制 抛异常
throw new Error("Maximum lock count exceeded");
// Reentrant acquire
setState(c + acquires); // 更新state
return true;
}
if (writerShouldBlock() || // 公平锁需要进入队列 非公平锁直接发起获取锁
!compareAndSetState(c, c + acquires)) // CAS state
return false;
setExclusiveOwnerThread(current); // 当前线程获取到锁
return true;
}
// 重写AQS共享锁方法
protected final boolean tryReleaseShared(int unused) {
Thread current = Thread.currentThread();
// 如果当前线程是第一个读线程
if (firstReader == current) {
// assert firstReaderHoldCount > 0;
// 读线程的重入次数为1
if (firstReaderHoldCount == 1)
firstReader = null; // 释放锁
else
firstReaderHoldCount--; // 减少重入次数
} else {
// 获取已被缓存的holdCounter 内部记录重入次数和线程ID
HoldCounter rh = cachedHoldCounter;
if (rh == null || rh.tid != getThreadId(current)) // 如果为空或者不是当前线程
rh = readHolds.get(); // 从ThreadLocal中获取自己的holdCounter
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; // 共享锁为高16位 一次减去一个单元 1<<16
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
// 重写AQS共享锁方法
protected final int tryAcquireShared(int unused) {
Thread current = Thread.currentThread();
int c = getState();
if (exclusiveCount(c) != 0 && // 独占锁个数不是0
getExclusiveOwnerThread() != current) // 并且拥有锁的线程不是当前线程
return -1;
int r = sharedCount(c); // 共享锁数量
if (!readerShouldBlock() && // 公平锁需要进入队列 非公平锁直接发起获取锁
r < MAX_COUNT &&
compareAndSetState(c, c + SHARED_UNIT)) { // 发起获取锁
if (r == 0) { // 如果没有读锁
firstReader = current; // 当前线程标记为第一个读线程
firstReaderHoldCount = 1; // 第一个读线程重入次数为1
} else if (firstReader == current) { // 如果第一个线程是当前线程
firstReaderHoldCount++; // 增加重入次数
} else {
// 获取已被缓存的holdCounter 内部记录重入次数和线程ID
HoldCounter rh = cachedHoldCounter;
if (rh == null || rh.tid != getThreadId(current))// 如果为空或者不是当前线程
cachedHoldCounter = rh = readHolds.get(); // 从ThreadLocal中获取自己的holdCounter 并更新缓存
else if (rh.count == 0) // 如果重入次数为0
readHolds.set(rh); // 添加到ThreadLocal中
rh.count++; // 增加重入次数
}
return 1;
}
return fullTryAcquireShared(current);
}
final int fullTryAcquireShared(Thread current) {
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;
} else { // 当前线程不是第一个读线程
if (rh == null) {
rh = cachedHoldCounter;
if (rh == null || rh.tid != getThreadId(current)) { // 如果已缓存的额holdCounter不是当前线程
rh = readHolds.get(); // 从ThreadLocal中取
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)) { // CAS获取锁
if (sharedCount(c) == 0) { // 共享锁数量为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;
}
}
}
// 如果有读锁 或者 持有锁的线程不是当前线程 会失败
// 说明如果一个线程持有了读锁 不能再持有写锁
final boolean tryWriteLock() {
Thread current = Thread.currentThread();
int c = getState();
if (c != 0) { // 有线程持有锁
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;
// 没有线程占有锁 state为0 或者持有写锁的是当前线程 获取锁成功
// CAS成功 获取到锁
setExclusiveOwnerThread(current);
return true;
}
// 如果有线程持有写锁并且不是当前线程 会失败
// 说明如果一个线程持有了写锁 可以再持有读锁
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;
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;
}
}
}
...
}
static final class NonfairSync extends Sync {
private static final long serialVersionUID = -8159625535654395037L;
final boolean writerShouldBlock() {
return false; // writers can always barge
}
final boolean readerShouldBlock() {
return apparentlyFirstQueuedIsExclusive();
}
}
static final class FairSync extends Sync {
private static final long serialVersionUID = -2274990926593161451L;
final boolean writerShouldBlock() {
return hasQueuedPredecessors();
}
final boolean readerShouldBlock() {
return hasQueuedPredecessors();
}
}
public static class ReadLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = -5992448646407690164L;
private final Sync sync;
protected ReadLock(ReentrantReadWriteLock lock) {
sync = lock.sync;
}
// 添加读锁
public void lock() {
// AQS获取共享锁
sync.acquireShared(1);
}
// 可中断读锁
public void lockInterruptibly() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
// 尝试获取读锁
public boolean tryLock() {
return sync.tryReadLock();
}
// 指定时间内尝试获取读锁
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
public void unlock() {
sync.releaseShared(1);
}
...
}
public static class WriteLock implements Lock, java.io.Serializable {
private final Sync sync;
protected WriteLock(ReentrantReadWriteLock lock) {
sync = lock.sync;
}
// 获取写锁
public void lock() {
// AQS获取独占锁
sync.acquire(1);
}
// 可中断写锁
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
// 尝试获取写锁
public boolean tryLock( ) {
return sync.tryWriteLock();
}
// 在指定时间内尝试获取锁
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
// 解锁
public void unlock() {
sync.release(1);
}
...
}
...
}