ReentrantReadWriteLock 源码分析:
1:数据结构:
成员变量:
private final ReentrantReadWriteLock.ReadLock readerLock; //读取锁
private final ReentrantReadWriteLock.WriteLock writerLock; //写入锁
final Sync sync; //Sync 对象,继承AQS对象
2:构造函数:
public ReentrantReadWriteLock() {
this(false);
}
public ReentrantReadWriteLock(boolean fair) { //默认 fair= false
sync = fair ? new FairSync() : new NonfairSync(); //默认创建一个 NonfairSync
readerLock = new ReadLock(this); //创建读取锁
writerLock = new WriteLock(this); //创建写入锁
}
3:接下来分析ReadLock 读取锁;
1):成员变量:
private final Sync sync; // ReadLock 内部维护的Sync对象,和ReentrantReadWriteLock中维护的Sync对象一致;
2):构造方法:
protected ReadLock(ReentrantReadWriteLock lock) {
sync = lock.sync; //将ReentrantReadWriteLock 构造函数中创建的Sync对象赋给ReadLock 中的Sync属性
}
4:下面分析ReadLock中的lock方法;
public void lock() {
sync.acquireShared(1);
}
acquireShared方法如下:
public final void acquireShared(int arg) { // arg=1
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}
下面依次分析 tryAcquireShared doAcquireShared这两个方法:
1): tryAcquireShared 方法:
protected final int tryAcquireShared(int unused) { // unused=1
Thread current = Thread.currentThread(); //当前线程
int c = getState(); //锁被持有的次数
if (exclusiveCount(c) != 0 &&
getExclusiveOwnerThread() != current) //若为互斥锁 且持有锁的线程不是当前线程则返回-1;
return -1;
int r = sharedCount(c); /获取锁的共享次数
if (!readerShouldBlock() &&
r < MAX_COUNT && //锁不需要阻塞等待,共享次数小于最大值,共享次数+1
compareAndSetState(c, c + SHARED_UNIT)) {
if (r == 0) { //第一次获取读取锁 则返回1 获取成功
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 1;
}
return fullTryAcquireShared(current); //当队列中首个节点是独占锁时会进入这个逻辑 这里就不分析了
}