AQS:
java 鎖的核心抽象類:
主要的思想,就是 violate 的 state + cas 來模擬钙皮,加鎖 和解鎖的操作;
waiting 的列表,使用的是一個 線程隊(duì)列伏社。
不同于 synchronizer 用的是 moniter enter/exit 特殊指令; 加 mointer對象(也包含塔淤,等待隊(duì)列摘昌,當(dāng)前線程等;)
每次進(jìn)入moniter標(biāo)識的區(qū)間高蜂,就會檢查響應(yīng)對象的monitor對象聪黎,當(dāng)前線程,重入次數(shù)备恤;等待隊(duì)列等等稿饰;
======================
AQS 的思想,可以鎖基本和 moniter是一樣的喉镰。 等待列表, 計(jì)數(shù)state惭笑,當(dāng)前線程侣姆。
其中 state 的取值范圍是 0/1沉噩,代表獨(dú)占鎖蚜厉,取大于0的值的時候,代表的是共享鎖畜眨;
其中等待隊(duì)列弯囊,用來處理 公平和非公平的問題痰哨;
=======AQS 有5個抽象方法,是需要更具自己的需求去實(shí)現(xiàn)的匾嘱。
tryAcquire
tryRelease
tryAcquireShared
tryReleaseShared
isHeldExclusively
以可重入lock為例:
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
就是在實(shí)現(xiàn) tryAcquire斤斧;
cas 設(shè)置狀態(tài):如果 state >0, 但是當(dāng)前線程是持有鎖的線程,就計(jì)數(shù)增加霎烙;
==== 在看額countlatch撬讽,是一個典型的 shared 鎖的 機(jī)制:
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
protected boolean tryReleaseShared(int releases) {
// Decrement count; signal when transition to zero
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
countLatch, 初始化的時候,就把 state 設(shè)置為 比如10悬垃;
countLatch. await() 的就是嘗試獲得鎖游昼; 但是 state!=0尝蠕,肯定是獲得不到的烘豌。所以等待;
countLatch.release,就是減少state看彼,以便 await的線程能夠獲得鎖廊佩;
其他的semphare ,用state來作為permit靖榕,permit 為0 的時候無法獲取需要wait标锄,不為0 可以獲取茁计;
cyclebarrier 使用的是條件condition料皇,一個lock 可以有多個condition,我們可以做到更加靈活的singal 對應(yīng)的線程星压; 同樣適用一個變量践剂,記錄barrier的個數(shù),當(dāng)達(dá)到0的時候娜膘,signalall, 通知所有的線程舷手,同時 reseet 變量,可以重復(fù)使用劲绪,這是和 countlatch不一樣的地方;