直接進(jìn)入lock()方法的tryAcquire方法
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if(c ==0) { //代表沒有線程持有獨(dú)占狀態(tài)师倔。當(dāng)前線程有機(jī)會(huì)去參與競(jìng)爭(zhēng)
if(!hasQueuedPredecessors() && //公平鎖和非公平鎖其它的都一樣,就是這個(gè)方法只有公平鎖才會(huì)去判斷,下面分析了這個(gè)方法的作用。
compareAndSetState(0,acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if(current == getExclusiveOwnerThread()) { //代表當(dāng)前有線程持有獨(dú)占狀態(tài)墓臭,并且不是當(dāng)前線程。所以當(dāng)前線程不能持有獨(dú)占,直接返回false
intnextc = c + acquires;
if(nextc <0)
throw newError("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
-------------------------------------------------------
分析hasQueuedPredecessors方法或链,
public final boolean hasQueuedPredecessors() {
// The correctness of this depends on head being initialized
// before tail and on head.next being accurate if the current
// thread is first in queue.
Node t =tail;// Read fields in reverse initialization order
Node h =head;
Node s;
return
h != t &&?
((s = h.next) ==null|| s.thread!= Thread.currentThread());
}
1、當(dāng)頭結(jié)點(diǎn)和尾節(jié)點(diǎn)不相等并且 如果head節(jié)點(diǎn)的next節(jié)點(diǎn)s不為空档押,并且s不是當(dāng)前線程澳盐。代表頭節(jié)點(diǎn)執(zhí)行完后s節(jié)點(diǎn)有可能被執(zhí)行。當(dāng)前線程無法參與競(jìng)爭(zhēng)令宿,所以返回true叼耙。
2、當(dāng)頭結(jié)點(diǎn)和尾節(jié)點(diǎn)不相等并且 如果head節(jié)點(diǎn)的next節(jié)點(diǎn)s不為空粒没,并且s是當(dāng)前線程筛婉。代表頭節(jié)點(diǎn)執(zhí)行完后s節(jié)點(diǎn)(當(dāng)前線程)有可能被執(zhí)行所以返回fasle。(代表上一層可以去競(jìng)爭(zhēng)獨(dú)占狀態(tài))
3、當(dāng)頭結(jié)點(diǎn)和尾節(jié)點(diǎn)不相等并且 如果head節(jié)點(diǎn)的next節(jié)點(diǎn)s為空爽撒,那么直接返回true入蛆,代表頭節(jié)點(diǎn)后面沒有節(jié)點(diǎn)。即當(dāng)前線程不是頭節(jié)點(diǎn)的next節(jié)點(diǎn)硕勿。返回true哨毁。不直接參與競(jìng)爭(zhēng)
4、當(dāng)頭結(jié)點(diǎn)和尾節(jié)點(diǎn)相等,返回false源武,代表這個(gè)節(jié)點(diǎn)執(zhí)行完之后沒有節(jié)點(diǎn)在同步隊(duì)列扼褪,當(dāng)前線程可以直接參與競(jìng)爭(zhēng)
以上四點(diǎn)保證了如果有其他的線程在頭節(jié)點(diǎn)的next上等待并且head節(jié)點(diǎn)的next節(jié)點(diǎn)不是當(dāng)前節(jié)點(diǎn)時(shí),那么這個(gè)線程不能直接參與競(jìng)爭(zhēng)粱栖,只能通過后面的循環(huán)cas方法去獲取獨(dú)占狀態(tài)话浇。在非公平鎖中,當(dāng)當(dāng)前線程去獲取state是0時(shí)闹究,當(dāng)前線程可以直接通過cas方法去嘗試獲取狀態(tài)幔崖,一旦成功,那么如果在頭節(jié)點(diǎn)后面原本有符合條件的等待執(zhí)行的線程A渣淤,就無法獲取獨(dú)占狀態(tài)岖瑰,因此,此時(shí)對(duì)于A就是不公平的砂代。
其它的邏輯都和非公平鎖一樣蹋订。