之前的acquire函數(shù)會先調(diào)用tryAcquire去嘗試獲得鎖,這個(gè)在每個(gè)具體類中實(shí)現(xiàn),這里看ReentrantLock中2個(gè)實(shí)現(xiàn)。
公平鎖FairSync中:
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {//狀態(tài)為0表示可以加鎖
if (!hasQueuedPredecessors() && //hasQueuedPredecessors表示之前的線程是否有在排隊(duì)的,這里加了!表示沒有排隊(duì)
compareAndSetState(0, acquires)) { //那么就去嘗試cas state
setExclusiveOwnerThread(current); //如果cas成功設(shè)置排他線程為當(dāng)前線程,表示成功得到鎖
return true;
}
}
else if (current == getExclusiveOwnerThread()) {//如果當(dāng)前的排他線程是當(dāng)前線程,表示是重入
int nextc = c + acquires; //重入計(jì)數(shù)器增加
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);//因?yàn)橐呀?jīng)獲得鎖了,所以不用cas去設(shè),直接設(shè)值就行
return true;
}
return false;
}
非公平鎖中:
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {//不同于公平鎖中,沒有hasQueuedPredecessors這個(gè)函數(shù),表示當(dāng)非公平鎖去加鎖的時(shí)候,不會去看有沒有線程在排隊(duì),直接去搶鎖,如果搶到了后續(xù)一樣。否則會去排隊(duì)(后續(xù)代碼再看)
//之前課程上講過”一朝排隊(duì)永遠(yuǎn)排隊(duì)“就是這個(gè)意思,排隊(duì)中的非公平并不會去搶先
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}