---
title: AQS 详解
description: AQSæ½è±¡éå忥卿·±åº¦è§£æï¼è¯¦è§£AQSæ ¸å¿åçãCLHéåç»æãç¬å éä¸å
±äº«éå®ç°ãReentrantLock/Semaphoreç忥å¨åºç¨ã线ç¨é»å¡å¤éæºå¶ã
category: Java
tag:
- Javaå¹¶å
head:
- - meta
- name: keywords
content: AQS,AbstractQueuedSynchronizer,éå忥å¨,ç¬å é,å
±äº«é,CLHéå,ReentrantLockå®ç°åç
---
## AQS ä»ç»
AQS çå
¨ç§°ä¸º `AbstractQueuedSynchronizer` ï¼ç¿»è¯è¿æ¥çææå°±æ¯æ½è±¡éå忥å¨ãè¿ä¸ªç±»å¨ `java.util.concurrent.locks` å
ä¸é¢ã

AQS å°±æ¯ä¸ä¸ªæ½è±¡ç±»ï¼ä¸»è¦ç¨æ¥æå»ºéå忥å¨ã
```java
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable {
}
```
AQS 为æå»ºéå忥卿ä¾äºä¸äºéç¨åè½çå®ç°ãå æ¤ï¼ä½¿ç¨ AQS è½ç®åä¸é«æå°æé åºåºç¨å¹¿æ³ç大éç忥å¨ï¼æ¯å¦æä»¬æå°ç `ReentrantLock`ï¼`Semaphore`ï¼å
¶ä»çè¯¸å¦ `ReentrantReadWriteLock`ï¼`SynchronousQueue`çççæ¯åºäº AQS çã
## AQS åç
å¨é¢è¯ä¸è¢«é®å°å¹¶åç¥è¯çæ¶åï¼å¤§å¤é½ä¼è¢«é®å°âè¯·ä½ è¯´ä¸ä¸èªå·±å¯¹äº AQS åçççè§£âãä¸é¢ç»å¤§å®¶ä¸ä¸ªç¤ºä¾ä¾å¤§å®¶åèï¼é¢è¯ä¸æ¯èé¢ï¼å¤§å®¶ä¸å®è¦å å
¥èªå·±çææ³ï¼å³ä½¿å å
¥ä¸äºèªå·±çææ³ä¹è¦ä¿è¯èªå·±è½å¤éä¿çè®²åºæ¥è䏿¯èåºæ¥ã
### AQS å¿«éäºè§£
å¨çæ£è®²è§£ AQS æºç ä¹åï¼éè¦å¯¹ AQS æä¸ä¸ªæ´ä½å±é¢ç认è¯ãè¿éä¼å
éè¿å 个é®é¢ï¼ä»æ´ä½å±é¢ä¸è®¤è¯ AQSï¼äºè§£ AQS 卿´ä¸ª Java å¹¶å䏿ä½äºçå±é¢ï¼ä¹åå¨å¦ä¹ AQS æºç çè¿ç¨ä¸ï¼æè½æ´å äºè§£åæ¥å¨å AQS ä¹é´çå
³ç³»ã
#### AQS çä½ç¨æ¯ä»ä¹ï¼
AQS è§£å³äºå¼åè
å¨å®ç°åæ¥å¨æ¶ç夿æ§é®é¢ã宿ä¾äºä¸ä¸ªéç¨æ¡æ¶ï¼ç¨äºå®ç°åç§åæ¥å¨ï¼ä¾å¦ **å¯éå
¥é**ï¼`ReentrantLock`ï¼ã**ä¿¡å·é**ï¼`Semaphore`ï¼å **å计æ¶å¨**ï¼`CountDownLatch`ï¼ãéè¿å°è£
åºå±ç线ç¨åæ¥æºå¶ï¼AQS å°å¤æç线ç¨ç®¡çé»è¾éèèµ·æ¥ï¼ä½¿å¼åè
åªé䏿³¨äºå
·ä½ç忥é»è¾ã
ç®åæ¥è¯´ï¼AQS æ¯ä¸ä¸ªæ½è±¡ç±»ï¼ä¸ºåæ¥å¨æä¾äºéç¨ç **æ§è¡æ¡æ¶**ãå®å®ä¹äº **èµæºè·ååéæ¾çéç¨æµç¨**ï¼èå
·ä½çèµæºè·åé»è¾åç±å
·ä½åæ¥å¨éè¿é忍¡æ¿æ¹æ³æ¥å®ç°ã å æ¤ï¼å¯ä»¥å° AQS ç使¯åæ¥å¨ç **åºç¡âåºåº§â**ï¼è忥å¨åæ¯åºäº AQS å®ç°ç **å
·ä½âåºç¨â**ã
#### AQS 为ä»ä¹ä½¿ç¨ CLH ééåçåä½ï¼
CLH 鿝ä¸ç§åºäº **èªæé** çä¼åå®ç°ã
å
说ä¸ä¸èªæéåå¨çé®é¢ï¼èªæééè¿çº¿ç¨ä¸æå¯¹ä¸ä¸ªåååéæ§è¡ `compareAndSet`ï¼ç®ç§° `CAS`ï¼æä½æ¥å°è¯è·åéãå¨é«å¹¶ååºæ¯ä¸ï¼å¤ä¸ªçº¿ç¨ä¼åæ¶ç«äºåä¸ä¸ªåååéï¼å®¹æé ææä¸ªçº¿ç¨ç `CAS` æä½é¿æ¶é´å¤±è´¥ï¼ä»èå¯¼è´ **â饥饿âé®é¢**ï¼æäºçº¿ç¨å¯è½æ°¸è¿æ æ³è·åéï¼ã
CLH ééè¿å¼å
¥ä¸ä¸ªé忥ç»ç»å¹¶åç«äºç线ç¨ï¼å¯¹èªæéè¿è¡äºæ¹è¿ï¼
- æ¯ä¸ªçº¿ç¨ä¼ä½ä¸ºä¸ä¸ªèç¹å å
¥å°éåä¸ï¼å¹¶éè¿èªæçæ§åä¸ä¸ªçº¿ç¨èç¹çç¶æï¼è䏿¯ç´æ¥ç«äºå
±äº«åéã
- çº¿ç¨æé¡ºåºæéï¼ç¡®ä¿å
¬å¹³æ§ï¼ä»èé¿å
äº â饥饿â é®é¢ã
AQSï¼AbstractQueuedSynchronizerï¼å¨ CLH éçåºç¡ä¸è¿ä¸æ¥ä¼åï¼å½¢æäºå
¶å
é¨ç **CLH éååä½**ãä¸»è¦æ¹è¿ç¹æä»¥ä¸ä¸¤æ¹é¢ï¼
1. **èªæ + é»å¡**ï¼ CLH é使ç¨çº¯èªææ¹å¼çå¾
éçéæ¾ï¼ä½å¤§éçèªææä½ä¼å ç¨è¿å¤ç CPU èµæºãAQS å¼å
¥äº **èªæ + é»å¡** çæ··åæºå¶ï¼
- å¦æçº¿ç¨è·åé失败ï¼ä¼å
çæèªæå°è¯è·åéï¼
- 妿ä»ç¶å¤±è´¥ï¼å线ç¨ä¼è¿å
¥é»å¡ç¶æï¼çå¾
被å¤éï¼ä»èåå° CPU çæµªè´¹ã
2. **ååéåæ¹ä¸ºååéå**ï¼CLH é使ç¨ååéåï¼èç¹åªç¥éå驱èç¹çç¶æï¼èå½æä¸ªèç¹éæ¾éæ¶ï¼éè¦éè¿éåå¤éåç»èç¹ãAQS å°éåæ¹ä¸º **ååéå**ï¼æ°å¢äº `next` æéï¼ä½¿å¾èç¹ä¸ä»
ç¥éå驱èç¹ï¼ä¹å¯ä»¥ç´æ¥å¤éåç»§èç¹ï¼ä»èç®åäºéåæä½ï¼æé«äºå¤éæçã
#### AQS çæ§è½æ¯è¾å¥½ï¼åå æ¯ä»ä¹ï¼
å 为 AQS å
é¨å¤§é使ç¨äº `CAS` æä½ã
AQS å
é¨éè¿é忥åå¨çå¾
ç线ç¨èç¹ãç±äºé忝å
±äº«èµæºï¼å¨å¤çº¿ç¨åºæ¯ä¸ï¼éè¦ä¿è¯éåçåæ¥è®¿é®ã
AQS å
é¨éè¿ `CAS` æä½æ¥æ§å¶éåçåæ¥è®¿é®ï¼`CAS` æä½ä¸»è¦ç¨äºæ§å¶ `éååå§å` ã `线ç¨èç¹å
¥é` 两个æä½çå¹¶åå®å
¨ãè½ç¶å©ç¨ `CAS` æ§å¶å¹¶åå®å
¨å¯ä»¥ä¿è¯æ¯è¾å¥½çæ§è½ï¼ä½åæ¶ä¼å¸¦æ¥æ¯è¾é«ç **ç¼ç å¤æåº¦** ã
#### AQS ä¸ä¸ºä»ä¹ Node èç¹éè¦ä¸åçç¶æï¼
AQS ä¸ç `waitStatus` ç¶æç±»ä¼¼äº **ç¶ææº** ï¼éè¿ä¸åç¶ææ¥è¡¨æ Node èç¹çä¸åå«ä¹ï¼å¹¶ä¸æ ¹æ®ä¸åæä½ï¼æ¥æ§å¶ç¶æä¹é´çæµè½¬ã
- ç¶æ `0` ï¼æ°èç¹å å
¥éåä¹åï¼åå§ç¶æä¸º `0` ã
- ç¶æ `SIGNAL` ï¼å½ææ°çèç¹å å
¥éåï¼æ¤æ¶æ°èç¹çåç»§èç¹ç¶æå°±ä¼ç± `0` æ´æ°ä¸º `SIGNAL` ï¼è¡¨ç¤ºåç»§èç¹éæ¾éä¹åï¼éè¦å¯¹æ°èç¹è¿è¡å¤éæä½ã妿å¤é `SIGNAL` ç¶æèç¹çåç»èç¹ï¼å°±ä¼å° `SIGNAL` ç¶ææ´æ°ä¸º `0` ãå³éè¿æ¸
é¤ `SIGNAL` ç¶æï¼è¡¨ç¤ºå·²ç»æ§è¡äºå¤éæä½ã
- ç¶æ `CANCELLED` ï¼å¦æä¸ä¸ªèç¹å¨éåä¸çå¾
è·åééæ¶ï¼å 为æç§åå 失败äºï¼è¯¥èç¹çç¶æå°±ä¼å为 `CANCELLED` ï¼è¡¨æåæ¶è·åéï¼è¿ç§ç¶æçèç¹æ¯å¼å¸¸çï¼æ æ³è¢«å¤éï¼ä¹æ æ³å¤éåç»§èç¹ã
### AQS æ ¸å¿ææ³
AQS æ ¸å¿ææ³æ¯ï¼å¦æè¢«è¯·æ±çå
±äº«èµæºç©ºé²ï¼åå°å½å请æ±èµæºç线ç¨è®¾ç½®ä¸ºææçå·¥ä½çº¿ç¨ï¼å¹¶ä¸å°å
±äº«èµæºè®¾ç½®ä¸ºéå®ç¶æãå¦æè¢«è¯·æ±çå
±äº«èµæºè¢«å ç¨ï¼é£ä¹å°±éè¦ä¸å¥çº¿ç¨é»å¡çå¾
以å被å¤éæ¶éåé
çæºå¶ï¼è¿ä¸ªæºå¶ AQS æ¯åºäº **CLH é** ï¼Craig, Landin, and Hagersten locksï¼ è¿ä¸æ¥ä¼åå®ç°çã
**CLH é** å¯¹èªæéè¿è¡äºæ¹è¿ï¼æ¯åºäºåé¾è¡¨çèªæéãå¨å¤çº¿ç¨åºæ¯ä¸ï¼ä¼å°è¯·æ±è·åéç线ç¨ç»ç»æä¸ä¸ªååéåï¼æ¯ä¸ªçå¾
ç线ç¨ä¼éè¿èªæè®¿é®åä¸ä¸ªçº¿ç¨èç¹çç¶æï¼åä¸ä¸ªèç¹éæ¾éä¹åï¼å½åèç¹æå¯ä»¥è·åéã**CLH é** çéåç»æå¦ä¸å¾æç¤ºã

AQS ä¸ä½¿ç¨ç **çå¾
éå** æ¯ CLH ééåçåä½ï¼æ¥ä¸æ¥ç®ç§°ä¸º CLH åä½éåï¼ã
AQS ç CLH åä½é忝ä¸ä¸ªååéåï¼ä¼ææ¶è·åä¸å°éç线ç¨å°è¢«å å
¥å°è¯¥éåä¸ï¼CLH åä½éåå忬ç CLH ééåçåºå«ä¸»è¦æä¸¤ç¹ï¼
- ç± **èªæ** ä¼å为 **èªæ + é»å¡** ï¼èªææä½çæ§è½å¾é«ï¼ä½å¤§éçèªææä½æ¯è¾å ç¨ CPU èµæºï¼å æ¤å¨ CLH åä½éåä¸ä¼å
éè¿èªæå°è¯è·åéï¼å¦æå¤±è´¥åè¿è¡é»å¡çå¾
ã
- ç± **ååéå** ä¼å为 **ååéå** ï¼å¨ CLH åä½éåä¸ï¼ä¼å¯¹çå¾
ç线ç¨è¿è¡é»å¡æä½ï¼å½éååè¾¹ç线ç¨éæ¾éä¹åï¼éè¦å¯¹åè¾¹ç线ç¨è¿è¡å¤éï¼å æ¤å¢å äº `next` æéï¼æä¸ºäºååéåã
AQS å°æ¯æ¡è¯·æ±å
±äº«èµæºç线ç¨å°è£
æä¸ä¸ª CLH åä½éåçä¸ä¸ªç»ç¹ï¼Nodeï¼æ¥å®ç°éçåé
ãå¨ CLH åä½éåä¸ï¼ä¸ä¸ªèç¹è¡¨ç¤ºä¸ä¸ªçº¿ç¨ï¼å®ä¿åç线ç¨çå¼ç¨ï¼threadï¼ã å½åèç¹å¨éåä¸çç¶æï¼waitStatusï¼ãå驱èç¹ï¼prevï¼ãåç»§èç¹ï¼nextï¼ã
AQS ä¸ç CLH åä½éåç»æå¦ä¸å¾æç¤ºï¼

å
³äº AQS æ ¸å¿æ°æ®ç»æ-CLH éç详ç»è§£è¯»ï¼å¼ºçæ¨èé
读 [Java AQS æ ¸å¿æ°æ®ç»æ-CLH é - Qunar ææ¯æ²é¾](https://mp.weixin.qq.com/s/jEx-4XhNGOFdCo4Nou5tqg) è¿ç¯æç« ã
AQS(`AbstractQueuedSynchronizer`)çæ ¸å¿åçå¾ï¼

AQS ä½¿ç¨ **int æååé `state` è¡¨ç¤ºåæ¥ç¶æ**ï¼éè¿å
ç½®ç **FIFO 线ç¨çå¾
/çå¾
éå** æ¥å®æè·åèµæºçº¿ç¨çæéå·¥ä½ã
`state` åéç± `volatile` 修饰ï¼ç¨äºå±ç¤ºå½å临çèµæºçè·åæ
åµã
```java
// å
±äº«åéï¼ä½¿ç¨volatile修饰ä¿è¯çº¿ç¨å¯è§æ§
private volatile int state;
```
å¦å¤ï¼ç¶æä¿¡æ¯ `state` å¯ä»¥éè¿ `protected` ç±»åç`getState()`ã`setState()`å`compareAndSetState()` è¿è¡æä½ãå¹¶ä¸ï¼è¿å ä¸ªæ¹æ³é½æ¯ `final` 修饰çï¼å¨åç±»ä¸æ æ³è¢«éåã
```java
//è¿ååæ¥ç¶æçå½åå¼
protected final int getState() {
return state;
}
// è®¾ç½®åæ¥ç¶æçå¼
protected final void setState(int newState) {
state = newState;
}
//ååå°ï¼CASæä½ï¼å°åæ¥ç¶æå¼è®¾ç½®ä¸ºç»å®å¼update妿å½ååæ¥ç¶æçå¼çäºexpectï¼ææå¼ï¼
protected final boolean compareAndSetState(int expect, int update) {
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
```
以å¯éå
¥çäºæ¥é `ReentrantLock` 为ä¾ï¼å®çå
é¨ç»´æ¤äºä¸ä¸ª `state` åéï¼ç¨æ¥è¡¨ç¤ºéçå ç¨ç¶æã`state` çåå§å¼ä¸º 0ï¼è¡¨ç¤ºéå¤äºæªéå®ç¶æãå½çº¿ç¨ A è°ç¨ `lock()` æ¹æ³æ¶ï¼ä¼å°è¯éè¿ `tryAcquire()` æ¹æ³ç¬å 该éï¼å¹¶è®© `state` çå¼å 1ã妿æåäºï¼é£ä¹çº¿ç¨ A å°±è·åå°äºéãå¦æå¤±è´¥äºï¼é£ä¹çº¿ç¨ A å°±ä¼è¢«å å
¥å°ä¸ä¸ªçå¾
éåï¼CLH åä½éåï¼ä¸ï¼ç´å°å
¶ä»çº¿ç¨éæ¾è¯¥éãåè®¾çº¿ç¨ A è·åéæåäºï¼éæ¾éä¹åï¼A 线ç¨èªå·±æ¯å¯ä»¥éå¤è·åæ¤éçï¼`state` ä¼ç´¯å ï¼ãè¿å°±æ¯å¯éå
¥æ§çä½ç°ï¼ä¸ä¸ªçº¿ç¨å¯ä»¥å¤æ¬¡è·ååä¸ä¸ªéèä¸ä¼è¢«é»å¡ã使¯ï¼è¿ä¹æå³çï¼ä¸ä¸ªçº¿ç¨å¿
须鿾ä¸è·åçæ¬¡æ°ç¸åçéï¼æè½è®© `state` çå¼åå° 0ï¼ä¹å°±æ¯è®©éæ¢å¤å°æªéå®ç¶æãåªæè¿æ ·ï¼å
¶ä»çå¾
ççº¿ç¨æè½ææºä¼è·å该éã
çº¿ç¨ A å°è¯è·åéçè¿ç¨å¦ä¸å¾æç¤ºï¼å¾æº[ä» ReentrantLock çå®ç°ç AQS çåçååºç¨ - ç¾å¢ææ¯å¢é](./reentrantlock.md)ï¼ï¼

å以å计æ¶å¨ `CountDownLatch` 以ä¾ï¼ä»»å¡å为 N 个å线ç¨å»æ§è¡ï¼`state` ä¹åå§å为 Nï¼æ³¨æ N è¦ä¸çº¿ç¨ä¸ªæ°ä¸è´ï¼ãè¿ N 个å线ç¨å¼å§æ§è¡ä»»å¡ï¼æ¯æ§è¡å®ä¸ä¸ªå线ç¨ï¼å°±è°ç¨ä¸æ¬¡ `countDown()` æ¹æ³ãè¯¥æ¹æ³ä¼å°è¯ä½¿ç¨ CAS(Compare and Swap) æä½ï¼è®© `state` çå¼åå° 1ã彿æçå线ç¨é½æ§è¡å®æ¯åï¼å³ `state` çå¼å为 0ï¼ï¼`CountDownLatch` ä¼è°ç¨ `unpark()` æ¹æ³ï¼å¤é主线ç¨ãè¿æ¶ï¼ä¸»çº¿ç¨å°±å¯ä»¥ä» `await()` æ¹æ³ï¼`CountDownLatch` ä¸ç`await()` æ¹æ³èé AQS ä¸çï¼è¿åï¼ç»§ç»æ§è¡åç»çæä½ã
### Node èç¹ waitStatus ç¶æå«ä¹
AQS ä¸ç `waitStatus` ç¶æç±»ä¼¼äº **ç¶ææº** ï¼éè¿ä¸åç¶ææ¥è¡¨æ Node èç¹çä¸åå«ä¹ï¼å¹¶ä¸æ ¹æ®ä¸åæä½ï¼æ¥æ§å¶ç¶æä¹é´çæµè½¬ã
| Node èç¹ç¶æ | å¼ | å«ä¹ |
| ------------- | --- | ------------------------------------------------------------------------------------------------------------------------- |
| `CANCELLED` | 1 | 表示线ç¨å·²ç»åæ¶è·åéã线ç¨å¨çå¾
è·åèµæºæ¶è¢«ä¸æãçå¾
èµæºè¶
æ¶ä¼æ´æ°ä¸ºè¯¥ç¶æã |
| `SIGNAL` | -1 | 表示åç»§èç¹éè¦å½åèç¹å¤éãå¨å½å线ç¨èç¹éæ¾éä¹åï¼éè¦å¯¹åç»§èç¹è¿è¡å¤éã |
| `CONDITION` | -2 | 表示èç¹å¨çå¾
Conditionãå½å
¶ä»çº¿ç¨è°ç¨äº Condition ç `signal()` æ¹æ³åï¼èç¹ä¼ä»çå¾
éå转移å°åæ¥éåä¸çå¾
è·åèµæºã |
| `PROPAGATE` | -3 | ç¨äºå
±äº«æ¨¡å¼ãå¨å
±äº«æ¨¡å¼ä¸ï¼å¯è½ä¼åºç°çº¿ç¨å¨éå䏿 æ³è¢«å¤éçæ
åµï¼å æ¤å¼å
¥äº `PROPAGATE` ç¶ææ¥è§£å³è¿ä¸ªé®é¢ã |
| | 0 | å å
¥éåçæ°èç¹çåå§ç¶æã |
å¨ AQS çæºç ä¸ï¼ç»å¸¸ä½¿ç¨ `> 0` ã `< 0` æ¥å¯¹ `waitStatus` è¿è¡å¤æã
妿 `waitStatus > 0` ï¼è¡¨æèç¹çç¶æå·²ç»åæ¶çå¾
è·åèµæºã
妿 `waitStatus < 0` ï¼è¡¨æèç¹çç¶æå¤äºæ£å¸¸çç¶æï¼å³æ²¡æåæ¶çå¾
ã
å
¶ä¸ `SIGNAL` ç¶ææ¯æéè¦çï¼èç¹ç¶ææµè½¬ä»¥åå¯¹åºæä½å¦ä¸ï¼
| ç¶ææµè½¬ | å¯¹åºæä½ |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `0` | æ°èç¹å
¥éæ¶ï¼åå§ç¶æä¸º `0` ã |
| `0 -> SIGNAL` | æ°èç¹å
¥éæ¶ï¼å®çåç»§èç¹ç¶æä¼ç± `0` æ´æ°ä¸º `SIGNAL` ã`SIGNAL` ç¶æè¡¨æè¯¥èç¹çåç»èç¹éè¦è¢«å¤éã |
| `SIGNAL -> 0` | å¨å¤éåç»§èç¹æ¶ï¼éè¦æ¸
é¤å½åèç¹çç¶æãé常åçå¨ `head` èç¹ï¼æ¯å¦ `head` èç¹çç¶æç± `SIGNAL` æ´æ°ä¸º `0` ï¼è¡¨ç¤ºå·²ç»å¯¹ `head` èç¹çåç»§èç¹å¤éäºã |
| `0 -> PROPAGATE` | AQS å
é¨å¼å
¥äº `PROPAGATE` ç¶æï¼ä¸ºäºè§£å³å¹¶ååºæ¯ä¸ï¼å¯è½é æç线ç¨èç¹æ æ³å¤éçæ
åµãï¼å¨ AQS å
±äº«æ¨¡å¼è·åèµæºçæºç åæä¼è®²å°ï¼ |
### èªå®ä¹åæ¥å¨
åºäº AQS å¯ä»¥å®ç°èªå®ä¹ç忥å¨ï¼ AQS æä¾äº 5 ä¸ªæ¨¡æ¿æ¹æ³ï¼æ¨¡æ¿æ¹æ³æ¨¡å¼ï¼ã妿éè¦èªå®ä¹åæ¥å¨ä¸è¬çæ¹å¼æ¯è¿æ ·ï¼æ¨¡æ¿æ¹æ³æ¨¡å¼å¾ç»å
¸çä¸ä¸ªåºç¨ï¼ï¼
1. èªå®ä¹ç忥å¨ç»§æ¿ `AbstractQueuedSynchronizer` ã
2. éå AQS æ´é²çæ¨¡æ¿æ¹æ³ã
**AQS 使ç¨äºæ¨¡æ¿æ¹æ³æ¨¡å¼ï¼èªå®ä¹åæ¥å¨æ¶éè¦éåä¸é¢å 个 AQS æä¾çé©åæ¹æ³ï¼**
```java
//ç¬å æ¹å¼ãå°è¯è·åèµæºï¼æååè¿åtrueï¼å¤±è´¥åè¿åfalseã
protected boolean tryAcquire(int)
//ç¬å æ¹å¼ãå°è¯éæ¾èµæºï¼æååè¿åtrueï¼å¤±è´¥åè¿åfalseã
protected boolean tryRelease(int)
//å
±äº«æ¹å¼ãå°è¯è·åèµæºãè´æ°è¡¨ç¤ºå¤±è´¥ï¼0表示æåï¼ä½æ²¡æå©ä½å¯ç¨èµæºï¼æ£æ°è¡¨ç¤ºæåï¼ä¸æå©ä½èµæºã
protected int tryAcquireShared(int)
//å
±äº«æ¹å¼ãå°è¯éæ¾èµæºï¼æååè¿åtrueï¼å¤±è´¥åè¿åfalseã
protected boolean tryReleaseShared(int)
//è¯¥çº¿ç¨æ¯å¦æ£å¨ç¬å èµæºãåªæç¨å°conditionæéè¦å»å®ç°å®ã
protected boolean isHeldExclusively()
```
**ä»ä¹æ¯é©åæ¹æ³å¢ï¼** é©åæ¹æ³æ¯ä¸ç§è¢«å£°æå¨æ½è±¡ç±»ä¸çæ¹æ³ï¼ä¸è¬ä½¿ç¨ `protected` å
³é®å修饰ï¼å®å¯ä»¥æ¯ç©ºæ¹æ³ï¼ç±åç±»å®ç°ï¼ï¼ä¹å¯ä»¥æ¯é»è®¤å®ç°çæ¹æ³ã模æ¿è®¾è®¡æ¨¡å¼éè¿é©åæ¹æ³æ§å¶åºå®æ¥éª¤çå®ç°ã
ç¯å¹
é®é¢ï¼è¿éå°±ä¸è¯¦ç»ä»ç»æ¨¡æ¿æ¹æ³æ¨¡å¼äºï¼ä¸å¤ªäºè§£çå°ä¼ä¼´å¯ä»¥ççè¿ç¯æç« ï¼[ç¨ Java8 æ¹é åçæ¨¡æ¿æ¹æ³æ¨¡å¼ççæ¯ yyds!](https://mp.weixin.qq.com/s/zpScSCktFpnSWHWIQem2jg)ã
é¤äºä¸é¢æå°çé©åæ¹æ³ä¹å¤ï¼AQS ç±»ä¸çå
¶ä»æ¹æ³é½æ¯ `final` ï¼æä»¥æ æ³è¢«å
¶ä»ç±»éåã
### AQS èµæºå
±äº«æ¹å¼
AQS å®ä¹ä¸¤ç§èµæºå
±äº«æ¹å¼ï¼`Exclusive`ï¼ç¬å ï¼åªæä¸ä¸ªçº¿ç¨è½æ§è¡ï¼å¦`ReentrantLock`ï¼å`Share`ï¼å
±äº«ï¼å¤ä¸ªçº¿ç¨å¯åæ¶æ§è¡ï¼å¦`Semaphore`/`CountDownLatch`ï¼ã
ä¸è¬æ¥è¯´ï¼èªå®ä¹åæ¥å¨çå
±äº«æ¹å¼è¦ä¹æ¯ç¬å ï¼è¦ä¹æ¯å
±äº«ï¼ä»ä»¬ä¹åªéå®ç°`tryAcquire-tryRelease`ã`tryAcquireShared-tryReleaseShared`ä¸çä¸ç§å³å¯ãä½ AQS 乿¯æèªå®ä¹åæ¥å¨åæ¶å®ç°ç¬å åå
±äº«ä¸¤ç§æ¹å¼ï¼å¦`ReentrantReadWriteLock`ã
### ç¬å 模å¼ä¸å
±äº«æ¨¡å¼çæ·±å
¥å¯¹æ¯
ä¸é¢ç®è¦ä»ç»äº AQS ç两ç§èµæºå
±äº«æ¹å¼ï¼ä¸é¢ä»å¤ä¸ªç»´åº¦å¯¹ç¬å 模å¼åå
±äº«æ¨¡å¼è¿è¡ç³»ç»å¯¹æ¯ï¼å¸®å©æ´æ·±å
¥å°çè§£äºè
çå·®å¼ã
#### ç¹æ§å¯¹æ¯
| 对æ¯ç»´åº¦ | ç¬å 模å¼ï¼Exclusiveï¼ | å
±äº«æ¨¡å¼ï¼Shareï¼ |
| --- | --- | --- |
| **å¹¶å度** | å䏿¶å»åªæä¸ä¸ªçº¿ç¨è½è·åå°èµæº | å䏿¶å»å¯ä»¥æå¤ä¸ªçº¿ç¨åæ¶è·åå°èµæº |
| **è·åèµæºå
¥å£** | `acquire(int arg)` | `acquireShared(int arg)` |
| **éæ¾èµæºå
¥å£** | `release(int arg)` | `releaseShared(int arg)` |
| **éè¦éåçæ¨¡æ¿æ¹æ³** | `tryAcquire(int)` / `tryRelease(int)` | `tryAcquireShared(int)` / `tryReleaseShared(int)` |
| **tryXxx è¿åå¼** | `boolean`ï¼`true` 表示è·å/éæ¾æå | `int`ï¼è·åæ¶ï¼ï¼è´æ°è¡¨ç¤ºå¤±è´¥ï¼0 表示æå使 å©ä½èµæºï¼æ£æ°è¡¨ç¤ºæå䏿å©ä½èµæºï¼`boolean`ï¼éæ¾æ¶ï¼ |
| **å¤éåç»§èç¹** | éæ¾èµæºæ¶å¤éä¸ä¸ªåç»§èç¹ | è·åèµæºæååï¼å¦æè¿æå©ä½èµæºï¼ä¼ç»§ç»å¤éåç»èç¹ï¼ä¼ æå¤éï¼ |
| **Node ç±»åæ è¯** | `Node.EXCLUSIVE`ï¼`null`ï¼ | `Node.SHARED`ï¼ä¸ä¸ªéæç `Node` å®ä¾ï¼ |
| **å
¸åå®ç°** | `ReentrantLock`ã`ReentrantReadWriteLock` çåé | `Semaphore`ã`CountDownLatch`ã`ReentrantReadWriteLock` ç读é |
#### `state` å¨ä¸å忥å¨ä¸çè¯ä¹
AQS ä¸ç `state` æ¯ä¸ä¸ªéç¨çåæ¥ç¶æåéï¼ä¸åç忥å¨èµäºå®ä¸åçå«ä¹ï¼
| åæ¥å¨ | æ¨¡å¼ | `state` çè¯ä¹ |
| --- | --- | --- |
| `ReentrantLock` | ç¬å | 表示éçéå
¥æ¬¡æ°ã`state == 0` 表示é空é²ï¼`state > 0` 表示é被ææï¼å¼ä¸ºéå
¥æ¬¡æ° |
| `ReentrantReadWriteLock` | ç¬å + å
±äº« | é« 16 ä½è¡¨ç¤ºè¯»éçæææ°éï¼å
±äº«ï¼ï¼ä½ 16 ä½è¡¨ç¤ºåéçéå
¥æ¬¡æ°ï¼ç¬å ï¼ |
| `Semaphore` | å
±äº« | 表示å¯ç¨è®¸å¯è¯çæ°éãæ¯æ¬¡ `acquire()` åå°ï¼`release()` å¢å |
| `CountDownLatch` | å
±äº« | 表示éè¦çå¾
ç计æ°ãæ¯æ¬¡ `countDown()` å 1ï¼å° 0 æ¶å¤éææçå¾
çº¿ç¨ |
ä¸é¢éè¿ä¸ä¸ªä»£ç ç¤ºä¾æ¥ç´è§æåç¬å 模å¼åå
±äº«æ¨¡å¼å¨ä½¿ç¨ä¸çåºå«ï¼
```java
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.ReentrantLock;
public class ExclusiveVsSharedDemo {
public static void main(String[] args) {
// ç¬å 模å¼ï¼å䏿¶å»åªæ 1 个线ç¨è½è¿å
¥ä¸´çåº
ReentrantLock lock = new ReentrantLock();
// å
±äº«æ¨¡å¼ï¼å䏿¶å»æå¤ 3 个线ç¨è½è¿å
¥ä¸´çåº
Semaphore semaphore = new Semaphore(3);
// ç¬å 模å¼ç¤ºä¾
Runnable exclusiveTask = () -> {
lock.lock();
try {
System.out.println(Thread.currentThread().getName()
+ " è·åå°ç¬å éï¼æ£å¨æ§è¡...");
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
};
// å
±äº«æ¨¡å¼ç¤ºä¾
Runnable sharedTask = () -> {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()
+ " è·åå°è®¸å¯è¯ï¼æ£å¨æ§è¡...");
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
semaphore.release();
}
};
System.out.println("=== ç¬å 模å¼ï¼ReentrantLockï¼===");
for (int i = 0; i < 5; i++) {
new Thread(exclusiveTask, "ç¬å 线ç¨-" + i).start();
}
try { Thread.sleep(3000); } catch (InterruptedException e) { }
System.out.println("\n=== å
±äº«æ¨¡å¼ï¼Semaphoreï¼===");
for (int i = 0; i < 5; i++) {
new Thread(sharedTask, "å
±äº«çº¿ç¨-" + i).start();
}
}
}
```
è¿è¡ä¸é¢ç代ç å¯ä»¥è§å¯å°ï¼ç¬å 模å¼ä¸ 5 个线ç¨ä¸¥æ ¼æé¡ºåºä¸ä¸ªä¸ä¸ªæ§è¡ï¼èå
±äº«æ¨¡å¼ä¸æå¤æ 3 个线ç¨åæ¶æ§è¡ã
### AQS èµæºè·åæºç åæï¼ç¬å 模å¼ï¼
AQS ä¸ä»¥ç¬å 模å¼è·åèµæºçå
¥å£æ¹æ³æ¯ `acquire()` ï¼å¦ä¸ï¼
```JAVA
// AQS
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
```
å¨ `acquire()` ä¸ï¼çº¿ç¨ä¼å
å°è¯è·åå
±äº«èµæºï¼å¦æè·å失败ï¼ä¼å°çº¿ç¨å°è£
为 Node èç¹å å
¥å° AQS ççå¾
éåä¸ï¼å å
¥éåä¹åï¼ä¼è®©çå¾
éåä¸ç线ç¨å°è¯è·åèµæºï¼å¹¶ä¸ä¼å¯¹çº¿ç¨è¿è¡é»å¡æä½ãåå«å¯¹åºä»¥ä¸ä¸ä¸ªæ¹æ³ï¼
- `tryAcquire()` ï¼å°è¯è·åéï¼æ¨¡æ¿æ¹æ³ï¼ï¼`AQS` 䏿ä¾å
·ä½å®ç°ï¼ç±åç±»å®ç°ã
- `addWaiter()` ï¼å¦æè·åé失败ï¼ä¼å°å½å线ç¨å°è£
为 Node èç¹å å
¥å° AQS ç CLH åä½éåä¸çå¾
è·åéã
- `acquireQueued()` ï¼å¯¹çº¿ç¨è¿è¡é»å¡ï¼å¹¶è°ç¨ `tryAcquire()` æ¹æ³è®©éåä¸ç线ç¨å°è¯è·åéã
#### `tryAcquire()` åæ
AQS ä¸å¯¹åºç `tryAcquire()` æ¨¡æ¿æ¹æ³å¦ä¸ï¼
```JAVA
// AQS
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
```
`tryAcquire()` æ¹æ³æ¯ AQS æä¾çæ¨¡æ¿æ¹æ³ï¼ä¸æä¾é»è®¤å®ç°ã
å æ¤ï¼è¿éåæ `tryAcquire()` æ¹æ³æ¶ï¼ä»¥ `ReentrantLock` çéå
¬å¹³éï¼ç¬å éï¼ä¸ºä¾è¿è¡åæï¼`ReentrantLock` å
é¨å®ç°ç `tryAcquire()` ä¼è°ç¨å°ä¸è¾¹ç `nonfairTryAcquire()` ï¼
```JAVA
// ReentrantLock
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
// 1ãè·å AQS ä¸ç state ç¶æ
int c = getState();
// 2ã妿 state 为 0ï¼è¯æé没æè¢«å
¶ä»çº¿ç¨å ç¨
if (c == 0) {
// 2.1ãéè¿ CAS 对 state è¿è¡æ´æ°
if (compareAndSetState(0, acquires)) {
// 2.2ã妿 CAS æ´æ°æåï¼å°±å°éçææè
设置为å½å线ç¨
setExclusiveOwnerThread(current);
return true;
}
}
// 3ã妿å½å线ç¨åéçææçº¿ç¨ç¸åï¼è¯´æåçäºãéçéå
¥ã
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
// 3.1ãå°éçéå
¥æ¬¡æ°å 1
setState(nextc);
return true;
}
// 4ã妿é被å
¶ä»çº¿ç¨å ç¨ï¼å°±è¿å falseï¼è¡¨ç¤ºè·åé失败
return false;
}
```
å¨ `nonfairTryAcquire()` æ¹æ³å
é¨ï¼ä¸»è¦éè¿ä¸¤ä¸ªæ ¸å¿æä½å»å®æèµæºçè·åï¼
- éè¿ `CAS` æ´æ° `state` åéã`state == 0` è¡¨ç¤ºèµæºæ²¡æè¢«å ç¨ã`state > 0` è¡¨ç¤ºèµæºè¢«å ç¨ï¼æ¤æ¶ `state` 表示éå
¥æ¬¡æ°ã
- éè¿ `setExclusiveOwnerThread()` 设置ææèµæºç线ç¨ã
å¦æçº¿ç¨æ´æ° `state` åéæåï¼å°±è¡¨æè·åå°äºèµæºï¼ å æ¤å°ææèµæºç线ç¨è®¾ç½®ä¸ºå½å线ç¨å³å¯ã
#### `addWaiter()` åæ
å¨éè¿ `tryAcquire()` æ¹æ³å°è¯è·åèµæºå¤±è´¥ä¹åï¼ä¼è°ç¨ `addWaiter()` æ¹æ³å°å½å线ç¨å°è£
为 Node èç¹å å
¥ `AQS` å
é¨çéåä¸ã`addWaite()` 代ç å¦ä¸ï¼
```JAVA
// AQS
private Node addWaiter(Node mode) {
// 1ãå°å½å线ç¨å°è£
为 Node èç¹ã
Node node = new Node(Thread.currentThread(), mode);
Node pred = tail;
// 2ã妿 pred ï¼= nullï¼åè¯æ tail èç¹å·²ç»è¢«åå§åï¼ç´æ¥å° Node èç¹å å
¥éåå³å¯ã
if (pred != null) {
node.prev = pred;
// 2.1ãéè¿ CAS æ§å¶å¹¶åå®å
¨ã
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
// 3ãåå§åéåï¼å¹¶å°æ°å建ç Node èç¹å å
¥éåã
enq(node);
return node;
}
```
**èç¹å
¥éçå¹¶åå®å
¨ï¼**
å¨ `addWaiter()` æ¹æ³ä¸ï¼éè¦æ§è¡ Node èç¹ **å
¥é** çæä½ãç±äºæ¯å¨å¤çº¿ç¨ç¯å¢ä¸ï¼å æ¤éè¦éè¿ `CAS` æä½ä¿è¯å¹¶åå®å
¨ã
éè¿ `CAS` æä½å»æ´æ° `tail` æéæåæ°å
¥éç Node èç¹ï¼`CAS` å¯ä»¥ä¿è¯åªæä¸ä¸ªçº¿ç¨ä¼æåä¿®æ¹ `tail` æéï¼ä»¥æ¤æ¥ä¿è¯ Node èç¹å
¥éæ¶çå¹¶åå®å
¨ã
**AQS å
é¨éåçåå§åï¼**
卿§è¡ `addWaiter()` æ¶ï¼å¦æåç° `pred == null` ï¼å³ `tail` æé为 nullï¼åè¯æéåæ²¡æåå§åï¼éè¦è°ç¨ `enq()` æ¹æ³åå§åéåï¼å¹¶å° `Node` èç¹å å
¥å°åå§ååçéåä¸ï¼ä»£ç å¦ä¸ï¼
```JAVA
// AQS
private Node enq(final Node node) {
for (;;) {
Node t = tail;
if (t == null) {
// 1ãéè¿ CAS æä½ä¿è¯éååå§åçå¹¶åå®å
¨
if (compareAndSetHead(new Node()))
tail = head;
} else {
// 2ãä¸ addWaiter() æ¹æ³ä¸èç¹å
¥éçæä½ç¸å
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
}
}
}
```
å¨ `enq()` æ¹æ³ä¸åå§åéåï¼å¨åå§åè¿ç¨ä¸ï¼ä¹éè¦éè¿ `CAS` æ¥ä¿è¯å¹¶åå®å
¨ã
åå§åéåæ»å
±å
å«ä¸¤ä¸ªæ¥éª¤ï¼åå§å `head` èç¹ã`tail` æå `head` èç¹ã
**åå§ååçéåå¦ä¸å¾æç¤ºï¼**

#### `acquireQueued()` åæ
ä¸ºäºæ¹ä¾¿é
读ï¼è¿éåè´´ä¸ä¸ `AQS` ä¸ `acquire()` è·åèµæºç代ç ï¼
```JAVA
// AQS
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
```
å¨ `acquire()` æ¹æ³ä¸ï¼éè¿ `addWaiter()` æ¹æ³å° `Node` èç¹å å
¥éåä¹åï¼å°±ä¼è°ç¨ `acquireQueued()` æ¹æ³ã代ç å¦ä¸ï¼
```JAVA
// AQSï¼ä»¤éåä¸çèç¹å°è¯è·åéï¼å¹¶ä¸å¯¹çº¿ç¨è¿è¡é»å¡ã
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
// 1ãå°è¯è·åéã
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
// 2ãå¤æçº¿ç¨æ¯å¦å¯ä»¥é»å¡ï¼å¦æå¯ä»¥ï¼åé»å¡å½å线ç¨ã
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
// 3ã妿è·åé失败ï¼å°±ä¼åæ¶è·åéï¼å°èç¹ç¶ææ´æ°ä¸º CANCELLEDã
if (failed)
cancelAcquire(node);
}
}
```
å¨ `acquireQueued()` æ¹æ³ä¸ï¼ä¸»è¦åä¸¤ä»¶äºæ
ï¼
- **å°è¯è·åèµæºï¼** å½å线ç¨å å
¥éåä¹åï¼å¦æåç°åç»§èç¹æ¯ `head` èç¹ï¼è¯´æå½åçº¿ç¨æ¯éåä¸ç¬¬ä¸ä¸ªçå¾
çèç¹ï¼äºæ¯è°ç¨ `tryAcquire()` å°è¯è·åèµæºã
- **é»å¡å½å线ç¨** ï¼å¦æå°è¯è·åèµæºå¤±è´¥ï¼å°±éè¦é»å¡å½å线ç¨ï¼çå¾
被å¤éä¹åè·åèµæºã
**1ãå°è¯è·åèµæº**
å¨ `acquireQueued()` æ¹æ³ä¸ï¼å°è¯è·åèµæºæ»å
±æ 2 个æ¥éª¤ï¼
- `p == head` ï¼è¡¨æå½åèç¹çåç»§èç¹ä¸º `head` èç¹ãæ¤æ¶å½åèç¹ä¸º AQS éåä¸ç第ä¸ä¸ªçå¾
èç¹ã
- `tryAcquire(arg) == true` ï¼è¡¨æå½å线ç¨å°è¯è·åèµæºæåã
卿åè·åèµæºä¹åï¼å°±éè¦å°å½å线ç¨çèç¹ **ä»çå¾
éåä¸ç§»é¤** ãç§»é¤æä½ä¸ºï¼å°å½åçå¾
ç线ç¨èç¹è®¾ç½®ä¸º `head` èç¹ï¼`head` èç¹æ¯èæèç¹ï¼å¹¶ä¸å䏿éè·åèµæºï¼ã
**2ãé»å¡å½å线ç¨**
å¨ `AQS` ä¸ï¼å½åèç¹çå¤ééè¦ä¾èµäºä¸ä¸ä¸ªèç¹ã妿ä¸ä¸ä¸ªèç¹åæ¶è·åéï¼å®çç¶æå°±ä¼å为 `CANCELLED` ï¼`CANCELLED` ç¶æçèç¹æ²¡æè·åå°éï¼ä¹å°±æ æ³æ§è¡è§£éæä½å¯¹å½åèç¹è¿è¡å¤éãå æ¤å¨é»å¡å½å线ç¨ä¹åï¼éè¦è·³è¿ `CANCELLED` ç¶æçèç¹ã
éè¿ `shouldParkAfterFailedAcquire()` æ¹æ³æ¥å¤æå½å线ç¨èç¹æ¯å¦å¯ä»¥é»å¡ï¼å¦ä¸ï¼
```JAVA
// AQSï¼å¤æå½å线ç¨èç¹æ¯å¦å¯ä»¥é»å¡ã
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
int ws = pred.waitStatus;
// 1ãåç»§èç¹ç¶ææ£å¸¸ï¼ç´æ¥è¿å true å³å¯ã
if (ws == Node.SIGNAL)
return true;
// 2ãws > 0 表示åç»§èç¹çç¶æå¼å¸¸ï¼å³ä¸º CANCELLED ç¶æï¼éè¦è·³è¿å¼å¸¸ç¶æçèç¹ã
if (ws > 0) {
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
pred.next = node;
} else {
// 3ã妿åç»§èç¹çç¶æä¸æ¯ SIGNALï¼ä¹ä¸æ¯ CANCELLEDï¼å°±å°ç¶æè®¾ç½®ä¸º SIGNALã
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;
}
```
`shouldParkAfterFailedAcquire()` æ¹æ³ä¸ç夿é»è¾ï¼
- 妿åç°åç»§èç¹çç¶ææ¯ `SIGNAL` ï¼åå¯ä»¥é»å¡å½å线ç¨ã
- 妿åç°åç»§èç¹çç¶ææ¯ `CANCELLED` ï¼åéè¦è·³è¿ `CANCELLED` ç¶æçèç¹ã
- 妿åç°åç»§èç¹çç¶æä¸æ¯ `SIGNAL` å `CANCELLED` ï¼è¡¨æåç»§èç¹çç¶æå¤äºæ£å¸¸çå¾
èµæºçç¶æï¼å æ¤å°åç»§èç¹çç¶æè®¾ç½®ä¸º `SIGNAL` ï¼è¡¨æè¯¥åç»§èç¹éè¦å¯¹åç»èç¹è¿è¡å¤éã
å½å¤æå½å线ç¨å¯ä»¥é»å¡ä¹åï¼éè¿è°ç¨ `parkAndCheckInterrupt()` æ¹æ³æ¥é»å¡å½å线ç¨ãå
é¨ä½¿ç¨äº `LockSupport` æ¥å®ç°é»å¡ã`LockSupoprt` åºå±æ¯åºäº `Unsafe` ç±»æ¥é»å¡çº¿ç¨ï¼ä»£ç å¦ä¸ï¼
```JAVA
// AQS
private final boolean parkAndCheckInterrupt() {
// 1ã线ç¨é»å¡å°è¿é
LockSupport.park(this);
// 2ã线ç¨è¢«å¤éä¹åï¼è¿å线ç¨ä¸æç¶æ
return Thread.interrupted();
}
```
**为ä»ä¹å¨çº¿ç¨è¢«å¤éä¹åï¼è¦è¿å线ç¨çä¸æç¶æå¢ï¼**
å¨ `parkAndCheckInterrupt()` æ¹æ³ä¸ï¼å½æ§è¡å® `LockSupport.park(this)` ï¼çº¿ç¨ä¼è¢«é»å¡ï¼ä»£ç å¦ä¸ï¼
```JAVA
// AQS
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);
// 线ç¨è¢«å¤éä¹åï¼éè¦è¿å线ç¨ä¸æç¶æ
return Thread.interrupted();
}
```
å½çº¿ç¨è¢«å¤éä¹åï¼éè¦æ§è¡ `Thread.interrupted()` æ¥è¿å线ç¨çä¸æç¶æï¼è¿æ¯ä¸ºä»ä¹å¢ï¼
è¿ä¸ªå线ç¨ç䏿å使ºå¶æå
³ç³»ï¼çº¿ç¨è¢«å¤éä¹åï¼å¹¶ä¸ç¡®å®æ¯è¢«ä¸æå¤éï¼è¿æ¯è¢« `LockSupport.unpark()` å¤éï¼å æ¤éè¦éè¿çº¿ç¨çä¸æç¶ææ¥å¤æã
**å¨ `acquire()` æ¹æ³ä¸ï¼ä¸ºä»ä¹éè¦è°ç¨ `selfInterrupt()` ï¼**
`acquire()` æ¹æ³ä»£ç å¦ä¸ï¼
```JAVA
// AQS
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
```
å¨ `acquire()` æ¹æ³ä¸ï¼å½ `if` è¯å¥çæ¡ä»¶è¿å `true` åï¼å°±ä¼è°ç¨ `selfInterrupt()` ï¼è¯¥æ¹æ³ä¼ä¸æå½å线ç¨ï¼ä¸ºä»ä¹éè¦ä¸æå½å线ç¨å¢ï¼
å½ `if` å¤æä¸º `true` æ¶ï¼éè¦ `tryAcquire()` è¿å `false` ï¼å¹¶ä¸ `acquireQueued()` è¿å `true` ã
å
¶ä¸ `acquireQueued()` æ¹æ³è¿åçæ¯çº¿ç¨è¢«å¤éä¹åç **ä¸æç¶æ** ï¼éè¿æ§è¡ `Thread.interrupted()` æ¥è¿åãè¯¥æ¹æ³å¨è¿åä¸æç¶æçåæ¶ï¼ä¼æ¸
é¤çº¿ç¨çä¸æç¶æã
å æ¤å¦æ `if` å¤æä¸º `true` ï¼è¡¨æçº¿ç¨çä¸æç¶æä¸º `true` ï¼ä½æ¯è°ç¨ `Thread.interrupted()` ä¹åï¼çº¿ç¨çä¸æç¶æè¢«æ¸
é¤ä¸º `false` ï¼å æ¤éè¦éæ°æ§è¡ `selfInterrupt()` æ¥éæ°è®¾ç½®çº¿ç¨çä¸æç¶æã
### AQS èµæºéæ¾æºç åæï¼ç¬å 模å¼ï¼
AQS ä¸ä»¥ç¬å 模å¼éæ¾èµæºçå
¥å£æ¹æ³æ¯ `release()` ï¼ä»£ç å¦ä¸ï¼
```JAVA
// AQS
public final boolean release(int arg) {
// 1ãå°è¯éæ¾é
if (tryRelease(arg)) {
Node h = head;
// 2ãå¤éåç»§èç¹
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
```
å¨ `release()` æ¹æ³ä¸ï¼ä¸»è¦å两件äºï¼å°è¯éæ¾éåå¤éåç»§èç¹ãå¯¹åºæ¹æ³å¦ä¸ï¼
**1ãå°è¯éæ¾é**
éè¿ `tryRelease()` æ¹æ³å°è¯éæ¾éï¼è¯¥æ¹æ³ä¸ºæ¨¡æ¿æ¹æ³ï¼ç±èªå®ä¹åæ¥å¨å®ç°ï¼å æ¤è¿éä»ç¶ä»¥ `ReentrantLock` ä¸ºä¾æ¥è®²è§£ã
`ReentrantLock` ä¸å®ç°ç `tryRelease()` æ¹æ³å¦ä¸ï¼
```JAVA
// ReentrantLock
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
// 1ã夿ææéççº¿ç¨æ¯å¦ä¸ºå½å线ç¨
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
// 2ã妿 state 为 0ï¼å表æå½å线ç¨å·²ç»æ²¡æéå
¥æ¬¡æ°ãå æ¤å° free æ´æ°ä¸º trueï¼è¡¨æè¯¥çº¿ç¨ä¼éæ¾éã
if (c == 0) {
free = true;
// 3ãæ´æ°ææèµæºç线ç¨ä¸º null
setExclusiveOwnerThread(null);
}
// 4ãæ´æ° state å¼
setState(c);
return free;
}
```
å¨ `tryRelease()` æ¹æ³ä¸ï¼ä¼å
计ç®éæ¾éä¹åç `state` å¼ï¼å¤æ `state` 弿¯å¦ä¸º 0ã
- 妿 `state == 0` ï¼è¡¨æè¯¥çº¿ç¨æ²¡æéå
¥æ¬¡æ°äºï¼æ´æ° `free = true` ï¼å¹¶ä¿®æ¹ææèµæºç线ç¨ä¸º nullï¼è¡¨æè¯¥çº¿ç¨å®å
¨éæ¾è¿æéã
- 妿 `state != 0` ï¼è¡¨æè¯¥çº¿ç¨è¿åå¨éå
¥æ¬¡æ°ï¼å æ¤ä¸æ´æ° `free` å¼ï¼`free` å¼ä¸º `false` 表æè¯¥çº¿ç¨æ²¡æå®å
¨éæ¾è¿æéã
ä¹åæ´æ° `state` å¼ï¼å¹¶è¿å `free` å¼ï¼`free` å¼è¡¨æçº¿ç¨æ¯å¦å®å
¨éæ¾éã
**2ãå¤éåç»§èç¹**
妿 `tryRelease()` è¿å `true` ï¼è¡¨æçº¿ç¨å·²ç»æ²¡æéå
¥æ¬¡æ°äºï¼éå·²ç»è¢«å®å
¨éæ¾ï¼å æ¤éè¦å¤éåç»§èç¹ã
å¨å¤éåç»§èç¹ä¹åï¼éè¦å¤ææ¯å¦å¯ä»¥å¤éåç»§èç¹ï¼å¤ææ¡ä»¶ä¸ºï¼ `h != null && h.waitStatus != 0` ãè¿éè§£éä¸ä¸ä¸ºä»ä¹è¦è¿æ ·å¤æï¼
- `h == null` ï¼è¡¨æ `head` èç¹è¿æ²¡æè¢«åå§åï¼ä¹å°±æ¯ AQS ä¸çéåæ²¡æè¢«åå§åï¼å æ¤æ æ³å¤ééåä¸ç线ç¨èç¹ã
- `h != null && h.waitStatus == 0` ï¼è¡¨æå¤´èç¹åååå§å宿¯ï¼èç¹çåå§åç¶æä¸º 0ï¼ï¼åç»§èç¹çº¿ç¨è¿æ²¡ææåå
¥éï¼å æ¤ä¸éè¦å¯¹åç»èç¹è¿è¡å¤éãï¼å½åç»§èç¹å
¥éä¹åï¼ä¼å°åç»§èç¹çç¶æä¿®æ¹ä¸º `SIGNAL` ï¼è¡¨æéè¦å¯¹åç»§èç¹è¿è¡å¤éï¼
- `h != null && h.waitStatus != 0` ï¼å
¶ä¸ `waitStatus` æå¯è½å¤§äº 0ï¼ä¹æå¯è½å°äº 0ãå
¶ä¸ `> 0` 表æèç¹å·²ç»åæ¶çå¾
è·åèµæºï¼`< 0` 表æèç¹å¤äºæ£å¸¸çå¾
ç¶æã
æ¥ä¸æ¥è¿å
¥ `unparkSuccessor()` æ¹æ³æ¥çå¦ä½å¤éåç»§èç¹ï¼
```JAVA
// AQSï¼è¿éçå
¥å node 为éåç头èç¹ï¼èæå¤´èç¹ï¼
private void unparkSuccessor(Node node) {
int ws = node.waitStatus;
// 1ãå°å¤´èç¹çç¶æè¿è¡æ¸
é¤ï¼ä¸ºåç»çå¤éååå¤ã
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);
Node s = node.next;
// 2ã妿åç»§èç¹å¼å¸¸ï¼åéè¦ä» tail ååéåï¼æ¾å°æ£å¸¸ç¶æçèç¹è¿è¡å¤éã
if (s == null || s.waitStatus > 0) {
s = null;
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
s = t;
}
if (s != null)
// 3ãå¤éåç»§èç¹
LockSupport.unpark(s.thread);
}
```
å¨ `unparkSuccessor()` ä¸ï¼å¦æå¤´èç¹çç¶æ `< 0` ï¼å¨æ£å¸¸æ
åµä¸ï¼åªè¦æåç»§èç¹ï¼å¤´èç¹çç¶æåºè¯¥ä¸º `SIGNAL` ï¼å³ -1ï¼ï¼è¡¨ç¤ºéè¦å¯¹åç»§èç¹è¿è¡å¤éï¼å æ¤è¿éæåæ¸
é¤å¤´èç¹çç¶ææ è¯ï¼å°ç¶æä¿®æ¹ä¸º 0ï¼è¡¨ç¤ºå·²ç»æ§è¡äºå¯¹åç»èç¹å¤éçæä½ã
妿 `s == null` æè
`s.waitStatus > 0` ï¼è¡¨æåç»§èç¹å¼å¸¸ï¼æ¤æ¶ä¸è½å¤éå¼å¸¸èç¹ï¼èæ¯è¦æ¾å°æ£å¸¸ç¶æçèç¹è¿è¡å¤éã
å æ¤éè¦ä» `tail` æéååéåï¼æ¥æ¾å°ç¬¬ä¸ä¸ªç¶ææ£å¸¸ï¼`waitStatus <= 0`ï¼çèç¹è¿è¡å¤éã
**为ä»ä¹è¦ä» `tail` æéååéåï¼è䏿¯ä» `head` æéååéåï¼å¯»æ¾æ£å¸¸ç¶æçèç¹å¢ï¼**
éåçæ¹åå **èç¹çå
¥éæä½** æå
³ãå
¥éæ¹æ³å¦ä¸ï¼
```JAVA
// AQSï¼èç¹å
¥éæ¹æ³
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
Node pred = tail;
if (pred != null) {
// 1ãå
ä¿®æ¹ prev æéã
node.prev = pred;
if (compareAndSetTail(pred, node)) {
// 2ãåä¿®æ¹ next æéã
pred.next = node;
return node;
}
}
enq(node);
return node;
}
```
å¨ `addWaiter()` æ¹æ³ä¸ï¼`node` èç¹å
¥ééè¦ä¿®æ¹ `node.prev` å `pred.next` 两个æéï¼ä½æ¯è¿ä¸¤ä¸ªæä½å¹¶ä¸æ¯ **ååæä½** ï¼å
ä¿®æ¹äº `node.prev` æéï¼ä¹åæä¿®æ¹ `pred.next` æéã
å¨æç«¯æ
åµä¸ï¼å¯è½ä¼åºç° `head` èç¹çä¸ä¸ä¸ªèç¹ç¶æä¸º `CANCELLED` ï¼æ¤æ¶æ°å
¥éçèç¹ä»
æ´æ°äº `node.prev` æéï¼è¿æªæ´æ° `pred.next` æéï¼å¦ä¸å¾ï¼

è¿æ ·å¦æä» `head` æéååéåï¼æ æ³æ¾å°æ°å
¥éçèç¹ï¼å æ¤éè¦ä» `tail` æéååé忾尿°å
¥éçèç¹ã
### å¾è§£ AQS å·¥ä½åçï¼ç¬å 模å¼ï¼
è³æ¤ï¼AQS ä¸ä»¥ç¬å 模å¼è·åèµæºãéæ¾èµæºçæºç 就讲å®äºã为äºå¯¹ AQS çå·¥ä½åçãèç¹ç¶æååæä¸ä¸ªæ´å æ¸
æ°ç认è¯ï¼æ¥ä¸æ¥ä¼éè¿ç»å¾çæ¹å¼æ¥äºè§£æ´ä¸ª AQS çå·¥ä½åçã
ç±äº AQS æ¯åºå±åæ¥å·¥å
·ï¼è·ååéæ¾èµæºçæ¹æ³å¹¶æ²¡ææä¾å
·ä½å®ç°ï¼å æ¤è¿éåºäº `ReentrantLock` æ¥ç»å¾è¿è¡è®²è§£ã
å设æ»å
±æ 3 个线ç¨å°è¯è·åéï¼çº¿ç¨åå«ä¸º `T1` ã `T2` å `T3` ã
æ¤æ¶ï¼åè®¾çº¿ç¨ `T1` å
è·åå°éï¼çº¿ç¨ `T2` æéçå¾
è·åéãå¨çº¿ç¨ `T2` è¿å
¥éåä¹åï¼éè¦å¯¹ AQS å
é¨éåè¿è¡åå§åã`head` èç¹å¨åå§ååç¶æä¸º `0` ãAQS å
é¨åå§ååçéåå¦ä¸å¾ï¼

æ¤æ¶ï¼çº¿ç¨ `T2` å°è¯è·åéãç±äºçº¿ç¨ `T1` ææéï¼å æ¤çº¿ç¨ `T2` ä¼è¿å
¥éåä¸çå¾
è·åéãåæ¶ä¼å°åç»§èç¹ï¼ `head` èç¹ï¼çç¶æç± `0` æ´æ°ä¸º `SIGNAL` ï¼è¡¨ç¤ºéè¦å¯¹ `head` èç¹çåç»§èç¹è¿è¡å¤éãæ¤æ¶ï¼AQS å
é¨éåå¦ä¸å¾æç¤ºï¼

æ¤æ¶ï¼çº¿ç¨ `T3` å°è¯è·åéãç±äºçº¿ç¨ `T1` ææéï¼å æ¤çº¿ç¨ `T3` ä¼è¿å
¥éåä¸çå¾
è·åéãåæ¶ä¼å°åç»§èç¹ï¼çº¿ç¨ `T2` èç¹ï¼çç¶æç± `0` æ´æ°ä¸º `SIGNAL` ï¼è¡¨ç¤ºçº¿ç¨ `T2` èç¹éè¦å¯¹åç»§èç¹è¿è¡å¤éãæ¤æ¶ï¼AQS å
é¨éåå¦ä¸å¾æç¤ºï¼

æ¤æ¶ï¼åè®¾çº¿ç¨ `T1` éæ¾éï¼ä¼å¤éåç»§èç¹ `T2` ãçº¿ç¨ `T2` 被å¤éåè·åå°éï¼å¹¶ä¸ä¼ä»çå¾
éåä¸éåºã
è¿éçº¿ç¨ `T2` èç¹éåºçå¾
éå并䏿¯ç´æ¥ä»éåç§»é¤ï¼èæ¯ä»¤çº¿ç¨ `T2` èç¹æä¸ºæ°ç `head` èç¹ï¼ä»¥æ¤æ¥éåºèµæºè·åççå¾
ãæ¤æ¶ AQS å
é¨éåå¦ä¸æç¤ºï¼

æ¤æ¶ï¼åè®¾çº¿ç¨ `T2` éæ¾éï¼ä¼å¤éåç»§èç¹ `T3` ãçº¿ç¨ `T3` è·åå°éä¹åï¼åæ ·ä¹éåºçå¾
éåï¼å³å°çº¿ç¨ `T3` èç¹å为 `head` èç¹æ¥éåºèµæºè·åççå¾
ãæ¤æ¶ AQS å
é¨éåå¦ä¸æç¤ºï¼

### AQS èµæºè·åæºç åæï¼å
±äº«æ¨¡å¼ï¼
AQS ä¸ä»¥å
±äº«æ¨¡å¼è·åèµæºçå
¥å£æ¹æ³æ¯ `acquireShared()` ï¼å¦ä¸ï¼
```JAVA
// AQS
public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}
```
å¨ `acquireShared()` æ¹æ³ä¸ï¼ä¼å
å°è¯è·åå
±äº«éï¼å¦æè·å失败ï¼åå°å½å线ç¨å å
¥å°éåä¸é»å¡ï¼çå¾
å¤éåå°è¯è·åå
±äº«éï¼åå«å¯¹åºä¸ä¸ä¸¤ä¸ªæ¹æ³ï¼`tryAcquireShared()` å `doAcquireShared()` ã
å
¶ä¸ `tryAcquireShared()` æ¹æ³æ¯ AQS æä¾çæ¨¡æ¿æ¹æ³ï¼ç±åæ¥å¨æ¥å®ç°å
·ä½é»è¾ãå æ¤è¿é以 `Semaphore` 为ä¾ï¼æ¥åæå
±äº«æ¨¡å¼ä¸ï¼å¦ä½è·åèµæºã
#### `tryAcquireShared()` åæ
`Semaphore` ä¸å®ç°äºå
¬å¹³éåéå
¬å¹³éï¼æ¥ä¸æ¥ä»¥éå
¬å¹³éä¸ºä¾æ¥åæ `tryAcquireShared()` æºç ã
`Semaphore` ä¸éåç `tryAcquireShared()` æ¹æ³ä¼è°ç¨ä¸è¾¹ç `nonfairTryAcquireShared()` æ¹æ³ï¼
```JAVA
// Semaphore éå AQS çæ¨¡æ¿æ¹æ³
protected int tryAcquireShared(int acquires) {
return nonfairTryAcquireShared(acquires);
}
// Semaphore
final int nonfairTryAcquireShared(int acquires) {
for (;;) {
// 1ãè·åå¯ç¨èµæºæ°éã
int available = getState();
// 2ã计ç®å©ä½èµæºæ°éã
int remaining = available - acquires;
// 3ã妿å©ä½èµæºæ°é < 0ï¼å说æèµæºä¸è¶³ï¼ç´æ¥è¿åï¼å¦æ CAS æ´æ° state æåï¼å说æå½å线ç¨è·åå°äºå
±äº«èµæºï¼ç´æ¥è¿åã
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
```
å¨å
±äº«æ¨¡å¼ä¸ï¼AQS ä¸ç `state` å¼è¡¨ç¤ºå
±äº«èµæºçæ°éã
å¨ `nonfairTryAcquireShared()` æ¹æ³ä¸ï¼ä¼å¨æ»å¾ªç¯ä¸ä¸æå°è¯è·åèµæºï¼å¦æ ãå©ä½èµæºæ°ä¸è¶³ã æè
ãå½åçº¿ç¨æåè·åèµæºã ï¼å°±éåºæ»å¾ªç¯ãæ¹æ³è¿å **å©ä½çèµæºæ°é** ï¼æ ¹æ®è¿åå¼çä¸åï¼å为 3 ç§æ
åµï¼
- **å©ä½èµæºæ°é > 0** ï¼è¡¨ç¤ºæåè·åèµæºï¼å¹¶ä¸åç»ç线ç¨ä¹å¯ä»¥æåè·åèµæºã
- **å©ä½èµæºæ°é = 0** ï¼è¡¨ç¤ºæåè·åèµæºï¼ä½æ¯åç»ççº¿ç¨æ æ³æåè·åèµæºã
- **å©ä½èµæºæ°é < 0** ï¼è¡¨ç¤ºè·åèµæºå¤±è´¥ã
#### `doAcquireShared()` åæ
ä¸ºäºæ¹ä¾¿é
读ï¼è¿éåè´´ä¸ä¸è·åèµæºçå
¥å£æ¹æ³ `acquireShared()` ï¼
```JAVA
// AQS
public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}
```
å¨ `acquireShared()` æ¹æ³ä¸ï¼ä¼å
éè¿ `tryAcquireShared()` å°è¯è·åèµæºã
妿åç°æ¹æ³çè¿åå¼ `< 0` ï¼å³å©ä½çèµæºæ°å°äº 0ï¼å表æå½å线ç¨è·åèµæºå¤±è´¥ãå æ¤ä¼è¿å
¥ `doAcquireShared()` æ¹æ³ï¼å°å½å线ç¨å å
¥å° AQS éåè¿è¡çå¾
ãå¦ä¸ï¼
```JAVA
// AQS
private void doAcquireShared(int arg) {
// 1ãå°å½å线ç¨å å
¥å°éåä¸çå¾
ã
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head) {
// 2ã妿å½åçº¿ç¨æ¯çå¾
éåç第ä¸ä¸ªèç¹ï¼åå°è¯è·åèµæºã
int r = tryAcquireShared(arg);
if (r >= 0) {
// 3ãå°å½å线ç¨èç¹ç§»åºçå¾
éåï¼å¹¶å¤éåç»çº¿ç¨èç¹ã
setHeadAndPropagate(node, r);
p.next = null; // help GC
if (interrupted)
selfInterrupt();
failed = false;
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
// 3ã妿è·åèµæºå¤±è´¥ï¼å°±ä¼åæ¶è·åèµæºï¼å°èç¹ç¶ææ´æ°ä¸º CANCELLEDã
if (failed)
cancelAcquire(node);
}
}
```
ç±äºå½å线ç¨å·²ç»å°è¯è·åèµæºå¤±è´¥äºï¼å æ¤å¨ `doAcquireShared()` æ¹æ³ä¸ï¼éè¦å°å½å线ç¨å°è£
为 Node èç¹ï¼å å
¥å°éåä¸è¿è¡çå¾
ã
以 **å
±äº«æ¨¡å¼** è·åèµæºå **ç¬å 模å¼** è·åèµæºæå¤§çä¸åä¹å¤å¨äºï¼å
±äº«æ¨¡å¼ä¸ï¼èµæºçæ°éå¯è½ä¼å¤§äº 1ï¼å³å¯ä»¥å¤ä¸ªçº¿ç¨åæ¶ææèµæºã
å æ¤å¨å
±äº«æ¨¡å¼ä¸ï¼å½çº¿ç¨çº¿ç¨è¢«å¤éä¹åï¼è·åå°äºèµæºï¼å¦æåç°è¿åå¨å©ä½èµæºï¼å°±ä¼å°è¯å¤éåè¾¹ç线ç¨å»å°è¯è·åèµæºã对åºç `setHeadAndPropagate()` æ¹æ³å¦ä¸ï¼
```JAVA
// AQS
private void setHeadAndPropagate(Node node, int propagate) {
Node h = head;
// 1ãå°å½å线ç¨èç¹ç§»åºçå¾
éåã
setHead(node);
// 2ãå¤éåç»çå¾
èç¹ã
if (propagate > 0 || h == null || h.waitStatus < 0 ||
(h = head) == null || h.waitStatus < 0) {
Node s = node.next;
if (s == null || s.isShared())
doReleaseShared();
}
}
```
å¨ `setHeadAndPropagate()` æ¹æ³ä¸ï¼å¤éåç»èç¹éè¦æ»¡è¶³ä¸å®çæ¡ä»¶ï¼ä¸»è¦éè¦æ»¡è¶³ 2 个æ¡ä»¶ï¼
- `propagate > 0` ï¼`propagate` 代表è·åèµæºä¹åå©ä½çèµæºæ°éï¼å¦æ `> 0` ï¼åå¯ä»¥å¤éåç»çº¿ç¨å»è·åèµæºã
- `h.waitStatus < 0` ï¼è¿éç `h` èç¹æ¯æ§è¡ `setHead()` ä¹åç `head` èç¹ã夿 `head.waitStatus` æ¶ä½¿ç¨ `< 0` ï¼ä¸»è¦ä¸ºäºç¡®å® `head` èç¹çç¶æä¸º `SIGNAL` æ `PROPAGATE` ã妿 `head` èç¹ä¸º `SIGNAL` ï¼åå¯ä»¥å¤éåç»èç¹ï¼å¦æ `head` èç¹ç¶æä¸º `PROPAGATE` ï¼ä¹å¯ä»¥å¤éåç»èç¹ï¼è¿æ¯ä¸ºäºè§£å³å¹¶ååºæ¯ä¸åºç°çé®é¢ï¼åç»ä¼ç»è®²ï¼ã
代ç ä¸å
³äº **å¤éåç»çå¾
èç¹** ç `if` 夿ç¨å¾®å¤æä¸äºï¼è¿éæ¥è®²ä¸ä¸ä¸ºä»ä¹è¿æ ·åï¼
```JAVA
if (propagate > 0 || h == null || h.waitStatus < 0 ||
(h = head) == null || h.waitStatus < 0)
```
- `h == null || h.waitStatus < 0` ï¼ `h == null` ç¨äºé²æ¢ç©ºæéå¼å¸¸ãæ£å¸¸æ
åµä¸ h ä¸ä¼ä¸º `null` ï¼å 为æ§è¡å°è¿éä¹åï¼å½åèç¹å·²ç»å å
¥å°éåä¸äºï¼éåä¸å¯è½è¿æ²¡æåå§åã
`h.waitStatus < 0` 主è¦å¤æ `head` èç¹çç¶ææ¯å¦ä¸º `SIGNAL` æè
`PROPAGATE` ï¼ç´æ¥ä½¿ç¨ `< 0` æ¥å¤ææ¯è¾æ¹ä¾¿ã
- `(h = head) == null || h.waitStatus < 0` ï¼å¦æå°è¿é说æä¹å夿ç `h.waitStatus < 0` ï¼è¯´æåå¨å¹¶åã
åæ¶åå¨å
¶ä»çº¿ç¨å¨å¤éåç»èç¹ï¼å·²ç»å° `head` èç¹çå¼ç± `SIGNAL` ä¿®æ¹ä¸º `0` äºãå æ¤ï¼è¿ééæ°è·åæ°ç `head` èç¹ï¼è¿æ¬¡è·åç `head` èç¹ä¸ºéè¿ `setHead()` 设置çå½å线ç¨èç¹ï¼ä¹å忬¡å¤æ `waitStatus` ç¶æã
妿 `if` æ¡ä»¶å¤æéè¿ï¼å°±ä¼èµ°å° `doReleaseShared()` æ¹æ³å¤éåç»çå¾
èç¹ï¼å¦ä¸ï¼
```JAVA
private void doReleaseShared() {
for (;;) {
Node h = head;
// 1ãéåä¸è³å°éè¦ä¸ä¸ªçå¾
ç线ç¨èç¹ã
if (h != null && h != tail) {
int ws = h.waitStatus;
// 2ã妿 head èç¹çç¶æä¸º SIGNALï¼åå¯ä»¥å¤éåç»§èç¹ã
if (ws == Node.SIGNAL) {
// 2.1 æ¸
é¤ head èç¹ç SIGNAL ç¶æï¼æ´æ°ä¸º 0ã表示已ç»å¤é该èç¹çåç»§èç¹äºã
if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
continue;
// 2.2 å¤éåç»§èç¹
unparkSuccessor(h);
}
// 3ã妿 head èç¹çç¶æä¸º 0ï¼åæ´æ°ä¸º PROPAGATEãè¿æ¯ä¸ºäºè§£å³å¹¶ååºæ¯ä¸åå¨çé®é¢ï¼æ¥ä¸æ¥ä¼ç»è®²ã
else if (ws == 0 &&
!compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
continue;
}
if (h == head)
break;
}
}
```
å¨ `doReleaseShared()` æ¹æ³ä¸ï¼ä¼å¤æ `head` èç¹ç `waitStatus` ç¶ææ¥å³å®æ¥ä¸æ¥çæä½ï¼æä¸¤ç§æ
åµï¼
- `head` èç¹çç¶æä¸º `SIGNAL` ï¼è¡¨æ `head` èç¹åå¨åç»§èç¹éè¦å¤éï¼å æ¤éè¿ `CAS` æä½å° `head` èç¹ç `SIGNAL` ç¶ææ´æ°ä¸º `0` ãéè¿æ¸
é¤ `SIGNAL` ç¶ææ¥è¡¨ç¤ºå·²ç»å¯¹ `head` èç¹çåç»§èç¹è¿è¡å¤éæä½äºã
- `head` èç¹çç¶æä¸º `0` ï¼è¡¨æåå¨å¹¶åæ
åµï¼éè¦å° `0` ä¿®æ¹ä¸º `PROPAGATE` æ¥ä¿è¯å¨å¹¶ååºæ¯ä¸å¯ä»¥æ£å¸¸å¤é线ç¨ã
#### 为ä»ä¹éè¦ `PROPAGATE` ç¶æï¼
å¨ `doReleaseShared()` éæ¾èµæºæ¶ï¼ç¬¬ 3 æ¥ä¸å¤ªå®¹æçè§£ï¼å³å¦æåç° `head` èç¹çç¶ææ¯ `0` ï¼å°±å° `head` èç¹çç¶æç± `0` æ´æ°ä¸º `PROPAGATE` ã
AQS ä¸ï¼Node èç¹ç `PROPAGATE` å°±æ¯ä¸ºäºå¤çå¹¶ååºæ¯ä¸å¯è½åºç°çæ æ³å¤é线ç¨èç¹çé®é¢ã`PROPAGATE` åªå¨ `doReleaseShared()` æ¹æ³ä¸ç¨å°ä¸æ¬¡ã
**æ¥ä¸æ¥éè¿æ¡ä¾åæï¼ä¸ºä»ä¹éè¦ `PROPAGATE` ç¶æï¼**
å¨å
±äº«æ¨¡å¼ä¸ï¼çº¿ç¨è·ååéæ¾èµæºçæ¹æ³è°ç¨é¾å¦ä¸ï¼
- 线ç¨è·åèµæºçæ¹æ³è°ç¨é¾ä¸ºï¼ `acquireShared() -> tryAcquireShared() -> 线ç¨é»å¡çå¾
å¤é -> tryAcquireShared() -> setHeadAndPropagate() -> if (å©ä½èµæºæ° > 0) || (head.waitStatus < 0) åå¤éåç»èç¹` ã
- 线ç¨éæ¾èµæºçæ¹æ³è°ç¨é¾ä¸ºï¼ `releaseShared() -> tryReleaseShared() -> doReleaseShared()` ã
**妿å¨éæ¾èµæºæ¶ï¼æ²¡æå° `head` èç¹çç¶æç± `0` æ¹ä¸º `PROPAGATE` ï¼**
å设æ»å
±æ 4 个线ç¨å°è¯ä»¥å
±äº«æ¨¡å¼è·åèµæºï¼æ»å
±æ 2 ä¸ªèµæºãåå§ `T3` å `T4` 线ç¨è·åå°äºèµæºï¼`T1` å `T2` çº¿ç¨æ²¡æè·åå°ï¼å æ¤å¨éå䏿éçåã
- 卿¶å» 1 æ¶ï¼çº¿ç¨ `T1` å `T2` å¨çå¾
éåä¸ï¼`T3` å `T4` ææèµæºãæ¤æ¶çå¾
éåå
èç¹ä»¥å对åºç¶æä¸ºï¼æ¬å·å
为èç¹ç `waitStatus` ç¶æï¼ï¼
`head(-1) -> T1(-1) -> T2(0)` ã
- 卿¶å» 2 æ¶ï¼çº¿ç¨ `T3` éæ¾èµæºï¼éè¿ `doReleaseShared()` æ¹æ³å° `head` èç¹çç¶æç± `SIGNAL` æ´æ°ä¸º `0` ï¼å¹¶å¤éçº¿ç¨ `T1` ï¼ä¹åçº¿ç¨ `T3` éåºã
çº¿ç¨ `T1` 被å¤éä¹åï¼éè¿ `tryAcquireShared()` è·åå°èµæºï¼ä½æ¯æ¤æ¶è¿æªæ¥å¾åæ§è¡ `setHeadAndPropagate()` å°èªå·±è®¾ç½®ä¸º `head` èç¹ãæ¤æ¶çå¾
éåå
èç¹ç¶æä¸ºï¼
`head(0) -> T1(-1) -> T2(0)` ã
- 卿¶å» 3 æ¶ï¼çº¿ç¨ `T4` éæ¾èµæºï¼ ç±äºæ¤æ¶ `head` èç¹çç¶æä¸º `0` ï¼å æ¤å¨ `doReleaseShared()` æ¹æ³ä¸æ æ³å¤é `head` çåç»§èç¹ï¼ ä¹åçº¿ç¨ `T4` éåºã
- 卿¶å» 4 æ¶ï¼çº¿ç¨ `T1` ç»§ç»æ§è¡ `setHeadAndPropagate()` æ¹æ³å°èªå·±è®¾ç½®ä¸º `head` èç¹ã
使¯æ¤æ¶ç±äºçº¿ç¨ `T1` æ§è¡ `tryAcquireShared()` æ¹æ³è¿åçå©ä½èµæºæ°ä¸º `0` ï¼å¹¶ä¸ `head` èç¹çç¶æä¸º `0` ï¼å æ¤çº¿ç¨ `T1` å¹¶ä¸ä¼å¨ `setHeadAndPropagate()` æ¹æ³ä¸å¤éåç»èç¹ãæ¤æ¶çå¾
éåå
èç¹ç¶æä¸ºï¼
`head(-1ï¼çº¿ç¨ T1 èç¹) -> T2(0)` ã
æ¤æ¶ï¼å°±å¯¼è´çº¿ç¨ `T2` èç¹å¨çå¾
éåä¸ï¼æ æ³è¢«å¤éãå¯¹åºæ¶å»è¡¨å¦ä¸ï¼
| æ¶å» | çº¿ç¨ T1 | çº¿ç¨ T2 | çº¿ç¨ T3 | çº¿ç¨ T4 | çå¾
éå |
| ------ | -------------------------------------------------------------- | -------- | ---------------- | ------------------------------------------------------------- | --------------------------------- |
| æ¶å» 1 | çå¾
éå | çå¾
éå | ææèµæº | ææèµæº | `head(-1) -> T1(-1) -> T2(0)` |
| æ¶å» 2 | ï¼æ§è¡ï¼è¢«å¤éåï¼è·åèµæºï¼ä½æªæ¥å¾åå°èªå·±è®¾ç½®ä¸º `head` èç¹ | çå¾
éå | ï¼æ§è¡ï¼éæ¾èµæº | ææèµæº | `head(0) -> T1(-1) -> T2(0)` |
| æ¶å» 3 | | çå¾
éå | å·²éåº | ï¼æ§è¡ï¼éæ¾èµæºãä½ `head` èç¹ç¶æä¸º `0` ï¼æ æ³å¤éåç»§èç¹ | `head(0) -> T1(-1) -> T2(0)` |
| æ¶å» 4 | ï¼æ§è¡ï¼å°èªå·±è®¾ç½®ä¸º `head` èç¹ | çå¾
éå | å·²éåº | å·²éåº | `head(-1ï¼çº¿ç¨ T1 èç¹) -> T2(0)` |
**妿å¨çº¿ç¨éæ¾èµæºæ¶ï¼å° `head` èç¹çç¶æç± `0` æ¹ä¸º `PROPAGATE` ï¼åå¯ä»¥è§£å³ä¸è¾¹åºç°çå¹¶åé®é¢ï¼å¦ä¸ï¼**
- 卿¶å» 1 æ¶ï¼çº¿ç¨ `T1` å `T2` å¨çå¾
éåä¸ï¼`T3` å `T4` ææèµæºãæ¤æ¶çå¾
éåå
èç¹ä»¥å对åºç¶æä¸ºï¼
`head(-1) -> T1(-1) -> T2(0)` ã
- 卿¶å» 2 æ¶ï¼çº¿ç¨ `T3` éæ¾èµæºï¼éè¿ `doReleaseShared()` æ¹æ³å° `head` èç¹çç¶æç± `SIGNAL` æ´æ°ä¸º `0` ï¼å¹¶å¤éçº¿ç¨ `T1` ï¼ä¹åçº¿ç¨ `T3` éåºã
çº¿ç¨ `T1` 被å¤éä¹åï¼éè¿ `tryAcquireShared()` è·åå°èµæºï¼ä½æ¯æ¤æ¶è¿æªæ¥å¾åæ§è¡ `setHeadAndPropagate()` å°èªå·±è®¾ç½®ä¸º `head` èç¹ãæ¤æ¶çå¾
éåå
èç¹ç¶æä¸ºï¼
`head(0) -> T1(-1) -> T2(0)` ã
- 卿¶å» 3 æ¶ï¼çº¿ç¨ `T4` éæ¾èµæºï¼ ç±äºæ¤æ¶ `head` èç¹çç¶æä¸º `0` ï¼å æ¤å¨ `doReleaseShared()` æ¹æ³ä¸ä¼å° `head` èç¹çç¶æç± `0` æ´æ°ä¸º `PROPAGATE` ï¼ ä¹åçº¿ç¨ `T4` éåºãæ¤æ¶çå¾
éåå
èç¹ç¶æä¸ºï¼
`head(PROPAGATE) -> T1(-1) -> T2(0)` ã
- 卿¶å» 4 æ¶ï¼çº¿ç¨ `T1` ç»§ç»æ§è¡ `setHeadAndPropagate()` æ¹æ³å°èªå·±è®¾ç½®ä¸º `head` èç¹ãæ¤æ¶çå¾
éåå
èç¹ç¶æä¸ºï¼
`head(-1ï¼çº¿ç¨ T1 èç¹) -> T2(0)` ã
- 卿¶å» 5 æ¶ï¼è½ç¶æ¤æ¶ç±äºçº¿ç¨ `T1` æ§è¡ `tryAcquireShared()` æ¹æ³è¿åçå©ä½èµæºæ°ä¸º `0` ï¼ä½æ¯ `head` èç¹ç¶æä¸º `PROPAGATE < 0` ï¼è¿éç `head` èç¹æ¯èç `head` èç¹ï¼è䏿¯åæä¸º `head` èç¹ççº¿ç¨ `T1` èç¹ï¼ã
å æ¤çº¿ç¨ `T1` ä¼å¨ `setHeadAndPropagate()` æ¹æ³ä¸å¤éåç» `T2` èç¹ï¼å¹¶å° `head` èç¹çç¶æç± `SIGNAL` æ´æ°ä¸º `0`ãæ¤æ¶çå¾
éåå
èç¹ç¶æä¸ºï¼
`head(0ï¼çº¿ç¨ T1 èç¹) -> T2(0)` ã
- 卿¶å» 6 æ¶ï¼çº¿ç¨ `T2` 被å¤éåï¼è·åå°èµæºï¼å¹¶å°èªå·±è®¾ç½®ä¸º `head` èç¹ãæ¤æ¶çå¾
éåå
èç¹ç¶æä¸ºï¼
`head(0ï¼çº¿ç¨ T2 èç¹)` ã
æäº `PROPAGATE` ç¶æï¼å°±å¯ä»¥é¿å
çº¿ç¨ `T2` æ æ³è¢«å¤éçæ
åµãå¯¹åºæ¶å»è¡¨å¦ä¸ï¼
| æ¶å» | çº¿ç¨ T1 | çº¿ç¨ T2 | çº¿ç¨ T3 | çº¿ç¨ T4 | çå¾
éå |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | ---------------- | ------------------------------------------------------------------- | ------------------------------------ |
| æ¶å» 1 | çå¾
éå | çå¾
éå | ææèµæº | ææèµæº | `head(-1) -> T1(-1) -> T2(0)` |
| æ¶å» 2 | ï¼æ§è¡ï¼è¢«å¤éåï¼è·åèµæºï¼ä½æªæ¥å¾åå°èªå·±è®¾ç½®ä¸º `head` èç¹ | çå¾
éå | ï¼æ§è¡ï¼éæ¾èµæº | ææèµæº | `head(0) -> T1(-1) -> T2(0)` |
| æ¶å» 3 | æªç»§ç»å䏿§è¡ | çå¾
éå | å·²éåº | ï¼æ§è¡ï¼éæ¾èµæºãæ¤æ¶ä¼å° `head` èç¹ç¶æç± `0` æ´æ°ä¸º `PROPAGATE` | `head(PROPAGATE) -> T1(-1) -> T2(0)` |
| æ¶å» 4 | ï¼æ§è¡ï¼å°èªå·±è®¾ç½®ä¸º `head` èç¹ | çå¾
éå | å·²éåº | å·²éåº | `head(-1ï¼çº¿ç¨ T1 èç¹) -> T2(0)` |
| æ¶å» 5 | ï¼æ§è¡ï¼ç±äº `head` èç¹ç¶æä¸º `PROPAGATE < 0` ï¼å æ¤ä¼å¨ `setHeadAndPropagate()` æ¹æ³ä¸å¤éåç»èç¹ï¼æ¤æ¶å°æ°ç `head` èç¹çç¶æç± `SIGNAL` æ´æ°ä¸º `0` ï¼å¹¶å¤éçº¿ç¨ `T2` | çå¾
éå | å·²éåº | å·²éåº | `head(0ï¼çº¿ç¨ T1 èç¹) -> T2(0)` |
| æ¶å» 6 | å·²éåº | ï¼æ§è¡ï¼çº¿ç¨ `T2` 被å¤éåï¼è·åå°èµæºï¼å¹¶å°èªå·±è®¾ç½®ä¸º `head` èç¹ | å·²éåº | å·²éåº | `head(0ï¼çº¿ç¨ T2 èç¹)` |
### AQS èµæºéæ¾æºç åæï¼å
±äº«æ¨¡å¼ï¼
AQS ä¸ä»¥å
±äº«æ¨¡å¼éæ¾èµæºçå
¥å£æ¹æ³æ¯ `releaseShared()` ï¼ä»£ç å¦ä¸ï¼
```JAVA
// AQS
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
```
å
¶ä¸ `tryReleaseShared()` æ¹æ³æ¯ AQS æä¾çæ¨¡æ¿æ¹æ³ï¼è¿éåæ ·ä»¥ `Semaphore` æ¥è®²è§£ï¼å¦ä¸ï¼
```JAVA
// Semaphore
protected final boolean tryReleaseShared(int releases) {
for (;;) {
int current = getState();
int next = current + releases;
if (next < current) // overflow
throw new Error("Maximum permit count exceeded");
if (compareAndSetState(current, next))
return true;
}
}
```
å¨ `Semaphore` å®ç°ç `tryReleaseShared()` æ¹æ³ä¸ï¼ä¼å¨æ»å¾ªç¯å
䏿å°è¯éæ¾èµæºï¼å³éè¿ `CAS` æä½æ¥æ´æ° `state` å¼ã
å¦ææ´æ°æåï¼åè¯æèµæºéæ¾æåï¼ä¼è¿å
¥å° `doReleaseShared()` æ¹æ³ã
`doReleaseShared()` æ¹æ³å¨åæè·åèµæºï¼å
±äº«æ¨¡å¼ï¼çé¨åå·²è¿è¡äºè¯¦ç»çæºç åæï¼æ¤å¤ä¸åéå¤ã
### Condition æ¡ä»¶éåç工使ºå¶
åé¢å¨ `waitStatus` ç¶æè¡¨æ ¼ä¸æå°è¿ `CONDITION`ï¼å¼ä¸º -2ï¼ç¶æï¼è¡¨ç¤ºèç¹å¨ Condition æ¡ä»¶éåä¸çå¾
ãè¿éç³»ç»è®²è§£ Condition æ¡ä»¶éåç工使ºå¶ã
#### ä»ä¹æ¯ Conditionï¼
`Condition` æ¯ `java.util.concurrent.locks` å
ä¸å®ä¹çæ¥å£ï¼å®æä¾äºç±»ä¼¼äº `Object.wait()` / `Object.notify()` ç线ç¨çå¾
/éç¥æºå¶ï¼ä½åè½æ´å 强大åçµæ´»ã`Condition` å¿
é¡»ä¸ `Lock` é
å使ç¨ï¼å°±å `wait/notify` å¿
é¡»ä¸ `synchronized` é
å使ç¨ä¸æ ·ã
ä¸ `Object` ç `wait/notify` ç¸æ¯ï¼`Condition` ç主è¦ä¼å¿å¨äºï¼
- **æ¯æå¤ä¸ªçå¾
éå**ï¼ä¸ä¸ª `Lock` å¯ä»¥å建å¤ä¸ª `Condition` å®ä¾ï¼ä¸åç线ç¨å¯ä»¥å¨ä¸åçæ¡ä»¶ä¸çå¾
ï¼å®ç°æ´ç²¾ç»ç线ç¨åä½ãè `synchronized` åªæä¸ä¸ªçå¾
éåã
- **æ¯æä¸ååºä¸æççå¾
**ï¼`Condition` æä¾äº `awaitUninterruptibly()` æ¹æ³ã
- **æ¯æè¶
æ¶çå¾
**ï¼`Condition` æä¾äº `awaitNanos(long)` å `await(long, TimeUnit)` æ¹æ³ï¼å¯ä»¥è®¾å®çå¾
çæªæ¢æ¶é´ã
#### AQS ä¸ç两ç§éå
å¨ AQS å
é¨å®é
ä¸ç»´æ¤äº **两ç§éå**ï¼
1. **忥éåï¼CLH åä½éåï¼**ï¼å°±æ¯åé¢è¯¦ç»åæè¿çååéåï¼ç¨äºåæ¾è·åèµæºå¤±è´¥èçå¾
ç线ç¨èç¹ã
2. **æ¡ä»¶éåï¼Condition Queueï¼**ï¼æ¯ä¸ä¸ªååé¾è¡¨ï¼ç¨äºåæ¾è°ç¨äº `Condition.await()` æ¹æ³èçå¾
ç线ç¨èç¹ãæ¯ä¸ª `Condition` å®ä¾ç»´æ¤ä¸ä¸ªç¬ç«çæ¡ä»¶éåã
æ¡ä»¶éåä¸çèç¹ä½¿ç¨ `Node` ç `nextWaiter` æéæ¥é¾æ¥ä¸ä¸ä¸ªèç¹ï¼å½¢æååé¾è¡¨ãæ¡ä»¶éåç头èç¹ä¸º `firstWaiter`ï¼å°¾èç¹ä¸º `lastWaiter`ã
#### Condition çæ ¸å¿å·¥ä½æµç¨
AQS çå
é¨ç±» `ConditionObject` å®ç°äº `Condition` æ¥å£ï¼å
¶æ ¸å¿æ¹æ³ä¸º `await()` å `signal()`ã
**`await()` æ¹æ³ç工使µç¨ï¼**
1. å°å½å线ç¨å°è£
为 `Node` èç¹ï¼`waitStatus` 设置为 `CONDITION`ï¼ï¼å å
¥å°æ¡ä»¶éåçå°¾é¨ã
2. å®å
¨éæ¾å½åçº¿ç¨ææçéï¼å³å° `state` å¼ç½®ä¸º 0ï¼ï¼å¹¶ä¿åéæ¾åç `state` å¼ã
3. é»å¡å½å线ç¨ï¼çå¾
被 `signal()` å¤éæè¢«ä¸æã
4. 被å¤éåï¼éæ°éè¿ `acquireQueued()` è¿å
¥åæ¥éåç«äºéï¼å¹¶æ¢å¤ä¹åä¿åç `state` å¼ï¼éå
¥æ¬¡æ°ï¼ã
**`signal()` æ¹æ³ç工使µç¨ï¼**
1. æ£æ¥è°ç¨ `signal()` ççº¿ç¨æ¯å¦ææéï¼ä¸ææåæåº `IllegalMonitorStateException`ï¼ã
2. å°æ¡ä»¶éåä¸ç¬¬ä¸ä¸ªçå¾
çèç¹ä»æ¡ä»¶éåç§»é¤ã
3. å°è¯¥èç¹ç `waitStatus` ä» `CONDITION` ä¿®æ¹ä¸º `0`ï¼å¹¶éè¿ `enq()` æ¹æ³å°å
¶å å
¥å°åæ¥éåçå°¾é¨ã
4. 妿忥éåä¸å驱èç¹çç¶æå¼å¸¸ï¼`CANCELLED`ï¼æè
CAS 设置å驱èç¹ç¶æä¸º `SIGNAL` 失败ï¼åç´æ¥å¤é该线ç¨ã
`signalAll()` æ¹æ³ä¸ `signal()` 类似ï¼åºå«å¨äºå®ä¼å°æ¡ä»¶éåä¸ç **ææ** èç¹é½è½¬ç§»å°åæ¥éåä¸ã
ä¸é¢ç代ç 示ä¾å±ç¤ºäº `Condition` çå
¸åç¨æ³ââå®ç°ä¸ä¸ªç®åçæçé»å¡éåï¼
```java
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class SimpleBlockingQueue