多線程在并發(fā)過程中發(fā)生競(jìng)爭(zhēng)時(shí),其實(shí)都滿足以下語(yǔ)義:
當(dāng)共有狀態(tài)(state)滿足某種條件時(shí),線程執(zhí)行;若不滿足,則排隊(duì)(queue)等待(park),直到被喚醒(unpark);
或者換一種表述:
當(dāng)線程獲取鎖時(shí),則繼續(xù)執(zhí)行;否則排隊(duì)(queue)等待(park),直到被喚醒(unpark);
AQS實(shí)際上就是對(duì)上述基本語(yǔ)義的包裝實(shí)現(xiàn)。
在不同的上下文中,滿足狀態(tài)的條件可能是不一樣的,因此要由子類去實(shí)現(xiàn);而排隊(duì)等待包括等待后的喚醒行為應(yīng)該都是相同的,所以這一部分已經(jīng)由AQS實(shí)現(xiàn)完畢。
AQS中定義了state變量來表示共有狀態(tài),子類需要從該變量獲取共有狀態(tài)當(dāng)前的值。
private volatile int state;
protected final int getState() { return state; }
protected final void setState(int newState) { state = newState; }
需要子類去實(shí)現(xiàn)的方法重要的有如下幾個(gè),比如第一個(gè)方法,若滿足狀態(tài)(獲得了鎖),則要返回true,否則返回false。
//獨(dú)占鎖
protected boolean tryAcquire(int arg) { throw new UnsupportedOperationException(); }
protected boolean tryRelease(int arg) { throw new UnsupportedOperationException(); }
//共享鎖
protected int tryAcquireShared(int arg) { throw new UnsupportedOperationException(); }
protected boolean tryReleaseShared(int arg) { throw new UnsupportedOperationException(); }
下表為各個(gè)類對(duì)state值的判斷
| Class | state | 鎖類型 | 說明 |
|---|---|---|---|
| ReentrantLock | 0 或 非0 | 獨(dú)占鎖 | state可以理解為鎖的唯一一把鑰匙,若為0,說明鑰匙沒人用,當(dāng)前線程獲取鑰匙開了鎖,其他線程都等待;否則若exclusiveThread==currentThread,則重入;否則阻塞 |
| CountDownLatch | 是否大于0 | 共享鎖 | state可以理解為倒計(jì)時(shí),若為0,說明倒計(jì)時(shí)結(jié)束,waiting()的線程可以執(zhí)行(可能有多個(gè)線程同時(shí)競(jìng)爭(zhēng)執(zhí)行) |
| Semaphore | 是否大于0 | 共享鎖 | 此時(shí)state可以理解為通行證,若大于0,說明還有證書,當(dāng)前線程可以執(zhí)行;否則阻塞 |
| ReentrantReadWriteLock.WriteLock | 0 或 非0 | 獨(dú)占鎖 | 獲取writeLock后,readLock無(wú)法再獲取 |
| ReentrantReadWriteLock.ReadLock | 是否大于0 | 共享鎖 | 獲取reakLock后,writeLock無(wú)法再獲取 |