ReentrantReadWriteLock中有2个对象ReadLock,WriteLock分别都有lock函数:
readlock.lock()
public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}
protected final int tryAcquireShared(int unused) {
Thread current = Thread.currentThread();
int c = getState();
if (exclusiveCount(c) != 0 && //如果已经有写锁
getExclusiveOwnerThread() != current) //且写锁线程不是当前线程,则获得锁失败返回
return -1;
int r = sharedCount(c);
if (!readerShouldBlock() && //看下面,如果读不需要被阻塞
r < MAX_COUNT &&
compareAndSetState(c, c + SHARED_UNIT)) {//且cas成功,表示获得到读锁
//下面这一大段都是缓存,提高执行效率,可以看上一节
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 1;
}
//如果获取锁失败,则再次去尝试获取锁
return fullTryAcquireShared(current);
}
readerShouldBlock分别在公平锁和非公平锁中:
FairSync.readerShouldBlock
final boolean readerShouldBlock() {
//看队列中是否有排队的线程,公平锁中只要前面有人在排队那么当前线程就应该被阻塞,不能去竞争锁,必须进入排队
return hasQueuedPredecessors();
}
NonfairSync.readerShouldBlock
final boolean readerShouldBlock() {
//队列中第一个排队的线程(队列中第二个元素)是写线程
//非公平锁中,如果第一个排队的是写,那么不能去竞争;如果是读,读读是共享的,而且是非公平,那么就可以去抢一下
return apparentlyFirstQueuedIsExclusive();
}