ReentrantReadWriteLock中有2個對象ReadLock,WriteLock分別都有l(wèi)ock函數(shù):
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 && //如果已經(jīng)有寫鎖
getExclusiveOwnerThread() != current) //且寫鎖線程不是當(dāng)前線程瓤檐,則獲得鎖失敗返回
return -1;
int r = sharedCount(c);
if (!readerShouldBlock() && //看下面赂韵,如果讀不需要被阻塞
r < MAX_COUNT &&
compareAndSetState(c, c + SHARED_UNIT)) {//且cas成功,表示獲得到讀鎖
//下面這一大段都是緩存挠蛉,提高執(zhí)行效率祭示,可以看上一節(jié)
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() {
//看隊列中是否有排隊的線程谴古,公平鎖中只要前面有人在排隊那么當(dāng)前線程就應(yīng)該被阻塞质涛,不能去競爭鎖,必須進入排隊
return hasQueuedPredecessors();
}
NonfairSync.readerShouldBlock
final boolean readerShouldBlock() {
//隊列中第一個排隊的線程(隊列中第二個元素)是寫線程
//非公平鎖中掰担,如果第一個排隊的是寫汇陆,那么不能去競爭;如果是讀带饱,讀讀是共享的毡代,而且是非公平阅羹,那么就可以去搶一下
return apparentlyFirstQueuedIsExclusive();
}