--- title: ä»ReentrantLockçå®ç°çAQSçåçååºç¨ category: Java tag: - Javaå¹¶å --- > æ¬æè½¬è½½èªï¼https://tech.meituan.com/2019/12/05/aqs-theory-and-apply.html > > ä½è ï¼ç¾å¢ææ¯å¢é Java ä¸ç大é¨ååæ¥ç±»ï¼SemaphoreãReentrantLock çï¼é½æ¯åºäº AbstractQueuedSynchronizerï¼ç®ç§°ä¸º AQSï¼å®ç°çãAQS æ¯ä¸ç§æä¾äºååå¼ç®¡çåæ¥ç¶æãé»å¡åå¤é线ç¨åè½ä»¥åé忍¡åçç®åæ¡æ¶ã æ¬æä¼ä»åºç¨å±éæ¸æ·±å ¥å°åçå±ï¼å¹¶éè¿ ReentrantLock çåºæ¬ç¹æ§å ReentrantLock ä¸ AQS çå ³èï¼æ¥æ·±å ¥è§£è¯» AQS ç¸å ³ç¬å éçç¥è¯ç¹ï¼åæ¶éåé®ççæ¨¡å¼æ¥å¸®å©å¤§å®¶çè§£ AQSãç±äºç¯å¹ åå ï¼æ¬ç¯æç« 主è¦éè¿° AQS ä¸ç¬å éçé»è¾å Sync Queueï¼ä¸è®²è¿°å å«å ±äº«éå Condition Queue çé¨åï¼æ¬ç¯æç« æ ¸å¿ä¸º AQS åçåæï¼åªæ¯ç®åä»ç»äº ReentrantLockï¼æå ´è¶£åå¦å¯ä»¥é 读ä¸ä¸ ReentrantLock çæºç ï¼ã ## 1 ReentrantLock ### 1.1 ReentrantLock ç¹æ§æ¦è§ ReentrantLock ææä¸ºå¯éå ¥éï¼æçæ¯ä¸ä¸ªçº¿ç¨è½å¤å¯¹ä¸ä¸ªä¸´çèµæºéå¤å éã为äºå¸®å©å¤§å®¶æ´å¥½å°çè§£ ReentrantLock çç¹æ§ï¼æä»¬å å° ReentrantLock è·å¸¸ç¨ç Synchronized è¿è¡æ¯è¾ï¼å ¶ç¹æ§å¦ä¸ï¼èè²é¨å为æ¬ç¯æç« 主è¦åæçç¹ï¼ï¼  ä¸é¢éè¿ä¼ªä»£ç ï¼è¿è¡æ´å ç´è§çæ¯è¾ï¼ ```java // **************************Synchronizedçä½¿ç¨æ¹å¼************************** // 1.ç¨äºä»£ç å synchronized (this) {} // 2.ç¨äºå¯¹è±¡ synchronized (object) {} // 3.ç¨äºæ¹æ³ public synchronized void test () {} // 4.å¯éå ¥ for (int i = 0; i < 100; i++) { synchronized (this) {} } // **************************ReentrantLockçä½¿ç¨æ¹å¼************************** public void test () throw Exception { // 1.åå§åéæ©å ¬å¹³éãéå ¬å¹³é ReentrantLock lock = new ReentrantLock(true); // 2.å¯ç¨äºä»£ç å lock.lock(); try { try { // 3.æ¯æå¤ç§å éæ¹å¼ï¼æ¯è¾çµæ´»; å ·æå¯éå ¥ç¹æ§ if(lock.tryLock(100, TimeUnit.MILLISECONDS)){ } } finally { // 4.æå¨éæ¾é lock.unlock() } } finally { lock.unlock(); } } ``` ### 1.2 ReentrantLock ä¸ AQS çå ³è éè¿ä¸ææä»¬å·²ç»äºè§£ï¼ReentrantLock æ¯æå ¬å¹³éåéå ¬å¹³éï¼å ³äºå ¬å¹³éåéå ¬å¹³éçåçåæï¼å¯åèã[ä¸å¯ä¸è¯´ç Javaâéâäº](https://mp.weixin.qq.com/s?__biz=MjM5NjQ5MTI5OA==&mid=2651749434&idx=3&sn=5ffa63ad47fe166f2f1a9f604ed10091&chksm=bd12a5778a652c61509d9e718ab086ff27ad8768586ea9b38c3dcf9e017a8e49bcae3df9bcc8&scene=38#wechat_redirect)ãï¼ï¼å¹¶ä¸ ReentrantLock çåºå±å°±æ¯ç± AQS æ¥å®ç°çãé£ä¹ ReentrantLock æ¯å¦ä½éè¿å ¬å¹³éåéå ¬å¹³éä¸ AQS å ³èèµ·æ¥å¢ï¼ æä»¬çéä»è¿ä¸¤è çå éè¿ç¨æ¥çè§£ä¸ä¸å®ä»¬ä¸ AQS ä¹é´çå ³ç³»ï¼å éè¿ç¨ä¸ä¸ AQS çå ³èæ¯è¾ææ¾ï¼è§£éæµç¨åç»ä¼ä»ç»ï¼ã éå ¬å¹³éæºç ä¸çå éæµç¨å¦ä¸ï¼ ```java // java.util.concurrent.locks.ReentrantLock#NonfairSync // éå ¬å¹³é static final class NonfairSync extends Sync { ... final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } ... } ``` è¿å代ç çå«ä¹ä¸ºï¼ - è¥éè¿ CAS 设置åé Stateï¼åæ¥ç¶æï¼æåï¼ä¹å°±æ¯è·åéæåï¼åå°å½å线ç¨è®¾ç½®ä¸ºç¬å 线ç¨ã - è¥éè¿ CAS 设置åé Stateï¼åæ¥ç¶æï¼å¤±è´¥ï¼ä¹å°±æ¯è·åé失败ï¼åè¿å ¥ Acquire æ¹æ³è¿è¡åç»å¤çã ç¬¬ä¸æ¥å¾å¥½çè§£ï¼ä½ç¬¬äºæ¥è·åé失败åï¼åç»çå¤ççç¥æ¯æä¹æ ·çå¢ï¼è¿åå¯è½ä¼æä»¥ä¸æèï¼ - æä¸ªçº¿ç¨è·åé失败çåç»æµç¨æ¯ä»ä¹å¢ï¼æä»¥ä¸ä¸¤ç§å¯è½ï¼ (1) å°å½å线ç¨è·éç»æè®¾ç½®ä¸ºå¤±è´¥ï¼è·åéæµç¨ç»æãè¿ç§è®¾è®¡ä¼æå¤§éä½ç³»ç»çå¹¶å度ï¼å¹¶ä¸æ»¡è¶³æä»¬å®é çéæ±ãæä»¥å°±éè¦ä¸é¢è¿ç§æµç¨ï¼ä¹å°±æ¯ AQS æ¡æ¶çå¤çæµç¨ã (2) åå¨æç§æéçåæºå¶ï¼çº¿ç¨ç»§ç»çå¾ ï¼ä»ç¶ä¿çè·åéçå¯è½ï¼è·åéæµç¨ä»å¨ç»§ç»ã - 对äºé®é¢ 1 ç第äºç§æ åµï¼æ¢ç¶è¯´å°äºæéçåæºå¶ï¼é£ä¹å°±ä¸å®ä¼ææç§éåå½¢æï¼è¿æ ·çé忝ä»ä¹æ°æ®ç»æå¢ï¼ - å¤äºæéçåæºå¶ä¸ç线ç¨ï¼ä»ä¹æ¶åå¯ä»¥ææºä¼è·åéå¢ï¼ - 妿å¤äºæéçåæºå¶ä¸ç线ç¨ä¸ç´æ æ³è·åéï¼è¿æ¯éè¦ä¸ç´çå¾ åï¼è¿æ¯æå«ççç¥æ¥è§£å³è¿ä¸é®é¢ï¼ 带çéå ¬å¹³éçè¿äºé®é¢ï¼åçä¸å ¬å¹³éæºç ä¸è·éçæ¹å¼ï¼ ```java // java.util.concurrent.locks.ReentrantLock#FairSync static final class FairSync extends Sync { ... final void lock() { acquire(1); } ... } ``` çå°è¿å代ç ï¼æä»¬å¯è½ä¼åå¨è¿ç§çé®ï¼Lock 彿°éè¿ Acquire æ¹æ³è¿è¡å éï¼ä½æ¯å ·ä½æ¯å¦ä½å éçå¢ï¼ ç»åå ¬å¹³éåéå ¬å¹³éçå éæµç¨ï¼è½ç¶æµç¨ä¸æä¸å®çä¸åï¼ä½æ¯é½è°ç¨äº Acquire æ¹æ³ï¼è Acquire æ¹æ³æ¯ FairSync å UnfairSync çç¶ç±» AQS ä¸çæ ¸å¿æ¹æ³ã 对äºä¸è¾¹æå°çé®é¢ï¼å ¶å®å¨ ReentrantLock ç±»æºç ä¸é½æ æ³è§£çï¼èè¿äºé®é¢ççæ¡ï¼é½æ¯ä½äº Acquire æ¹æ³æå¨çç±» AbstractQueuedSynchronizer ä¸ï¼ä¹å°±æ¯æ¬æçæ ¸å¿ââAQSãä¸é¢æä»¬ä¼å¯¹ AQS 以å ReentrantLock å AQS çå ³èå详ç»ä»ç»ï¼ç¸å ³é®é¢çæ¡ä¼å¨ 2.3.5 å°èä¸è§£çï¼ã ## 2 AQS é¦å ï¼æä»¬éè¿ä¸é¢çæ¶æå¾æ¥æ´ä½äºè§£ä¸ä¸ AQS æ¡æ¶ï¼  - ä¸å¾ä¸æé¢è²ç为 Methodï¼æ é¢è²ç为 Attributionã - æ»çæ¥è¯´ï¼AQS æ¡æ¶å ±å为äºå±ï¼èªä¸èä¸ç±æµ å ¥æ·±ï¼ä» AQS 坹夿´é²ç API å°åºå±åºç¡æ°æ®ã - 彿èªå®ä¹åæ¥å¨æ¥å ¥æ¶ï¼åªééå第ä¸å±æéè¦çé¨åæ¹æ³å³å¯ï¼ä¸éè¦å ³æ³¨åºå±å ·ä½çå®ç°æµç¨ãå½èªå®ä¹åæ¥å¨è¿è¡å éæè è§£éæä½æ¶ï¼å ç»è¿ç¬¬ä¸å±ç API è¿å ¥ AQS å 鍿¹æ³ï¼ç¶åç»è¿ç¬¬äºå±è¿è¡éçè·åï¼æ¥ç对äºè·åéå¤±è´¥çæµç¨ï¼è¿å ¥ç¬¬ä¸å±å第åå±ççå¾ éåå¤çï¼èè¿äºå¤çæ¹å¼åä¾èµäºç¬¬äºå±çåºç¡æ°æ®æä¾å±ã ä¸é¢æä»¬ä¼ä»æ´ä½å°ç»èï¼ä»æµç¨å°æ¹æ³éä¸åæ AQS æ¡æ¶ï¼ä¸»è¦åæè¿ç¨å¦ä¸ï¼  ### 2.1 åçæ¦è§ AQS æ ¸å¿ææ³æ¯ï¼å¦æè¢«è¯·æ±çå ±äº«èµæºç©ºé²ï¼é£ä¹å°±å°å½å请æ±èµæºç线ç¨è®¾ç½®ä¸ºææçå·¥ä½çº¿ç¨ï¼å°å ±äº«èµæºè®¾ç½®ä¸ºéå®ç¶æï¼å¦æå ±äº«èµæºè¢«å ç¨ï¼å°±éè¦ä¸å®çé»å¡çå¾ å¤éæºå¶æ¥ä¿è¯éåé ãè¿ä¸ªæºå¶ä¸»è¦ç¨çæ¯ CLH éåçåä½å®ç°çï¼å°ææ¶è·åä¸å°éç线ç¨å å ¥å°éåä¸ã CLHï¼CraigãLandin and Hagersten éåï¼æ¯ååé¾è¡¨ï¼AQS ä¸çé忝 CLH åä½çèæååéåï¼FIFOï¼ï¼AQS æ¯éè¿å°æ¯æ¡è¯·æ±å ±äº«èµæºç线ç¨å°è£ æä¸ä¸ªèç¹æ¥å®ç°éçåé ã 主è¦åçå¾å¦ä¸ï¼  AQS 使ç¨ä¸ä¸ª Volatile ç int ç±»åçæååéæ¥è¡¨ç¤ºåæ¥ç¶æï¼éè¿å ç½®ç FIFO éåæ¥å®æèµæºè·åçæéå·¥ä½ï¼éè¿ CAS 宿坹 State å¼çä¿®æ¹ã #### 2.1.1 AQS æ°æ®ç»æ å æ¥çä¸ AQS ä¸æåºæ¬çæ°æ®ç»æââNodeï¼Node å³ä¸ºä¸é¢ CLH åä½éåä¸çèç¹ã  è§£éä¸ä¸å ä¸ªæ¹æ³å屿§å¼çå«ä¹ï¼ | æ¹æ³å屿§å¼ | å«ä¹ | | :----------- | :----------------------------------------------------------------------------------------------- | | waitStatus | å½åèç¹å¨éåä¸çç¶æ | | thread | 表示å¤äºè¯¥èç¹ççº¿ç¨ | | prev | å驱æé | | predecessor | è¿åå驱èç¹ï¼æ²¡æçè¯æåº npe | | nextWaiter | æåä¸ä¸ä¸ªå¤äº CONDITION ç¶æçèç¹ï¼ç±äºæ¬ç¯æç« ä¸è®²è¿° Condition Queue éåï¼è¿ä¸ªæéä¸å¤ä»ç»ï¼ | | next | åç»§æé | 线ç¨ä¸¤ç§éçæ¨¡å¼ï¼ | æ¨¡å¼ | å«ä¹ | | :-------- | :----------------------------- | | SHARED | 表示线ç¨ä»¥å ±äº«ç模å¼çå¾ é | | EXCLUSIVE | è¡¨ç¤ºçº¿ç¨æ£å¨ä»¥ç¬å çæ¹å¼çå¾ é | waitStatus æä¸é¢å 个æä¸¾å¼ï¼ | æä¸¾ | å«ä¹ | | :-------- | :----------------------------------------------- | | 0 | å½ä¸ä¸ª Node 被åå§åçæ¶åçé»è®¤å¼ | | CANCELLED | 为 1ï¼è¡¨ç¤ºçº¿ç¨è·åéç请æ±å·²ç»åæ¶äº | | CONDITION | 为-2ï¼è¡¨ç¤ºèç¹å¨çå¾ éåä¸ï¼èç¹çº¿ç¨çå¾ å¤é | | PROPAGATE | 为-3ï¼å½å线ç¨å¤å¨ SHARED æ åµä¸ï¼è¯¥å段æä¼ä½¿ç¨ | | SIGNAL | 为-1ï¼è¡¨ç¤ºçº¿ç¨å·²ç»åå¤å¥½äºï¼å°±çèµæºéæ¾äº | #### 2.1.2 åæ¥ç¶æ State å¨äºè§£æ°æ®ç»æåï¼æ¥ä¸æ¥äºè§£ä¸ä¸ AQS çåæ¥ç¶æââStateãAQS ä¸ç»´æ¤äºä¸ä¸ªå为 state çåæ®µï¼æä¸ºåæ¥ç¶æï¼æ¯ç± Volatile 修饰çï¼ç¨äºå±ç¤ºå½å临çèµæºçè·éæ åµã ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer private volatile int state; ``` ä¸é¢æä¾äºå 个访é®è¿ä¸ªåæ®µçæ¹æ³ï¼ | æ¹æ³å | æè¿° | | :----------------------------------------------------------------- | :---------------------- | | protected final int getState() | è·å State çå¼ | | protected final void setState(int newState) | 设置 State çå¼ | | protected final boolean compareAndSetState(int expect, int update) | ä½¿ç¨ CAS æ¹å¼æ´æ° State | è¿å ä¸ªæ¹æ³é½æ¯ Final 修饰çï¼è¯´æåç±»ä¸æ æ³éåå®ä»¬ãæä»¬å¯ä»¥éè¿ä¿®æ¹ State åæ®µè¡¨ç¤ºçåæ¥ç¶ææ¥å®ç°å¤çº¿ç¨çç¬å 模å¼åå ±äº«æ¨¡å¼ï¼å éè¿ç¨ï¼ã   å¯¹äºæä»¬èªå®ä¹çåæ¥å·¥å ·ï¼éè¦èªå®ä¹è·ååæ¥ç¶æåéæ¾ç¶æçæ¹å¼ï¼ä¹å°±æ¯ AQS æ¶æå¾ä¸ç第ä¸å±ï¼API å±ã ### 2.2 AQS éè¦æ¹æ³ä¸ ReentrantLock çå ³è 仿¶æå¾ä¸å¯ä»¥å¾ç¥ï¼AQS æä¾äºå¤§éç¨äºèªå®ä¹åæ¥å¨å®ç°ç Protected æ¹æ³ãèªå®ä¹åæ¥å¨å®ç°çç¸å ³æ¹æ³ä¹åªæ¯ä¸ºäºéè¿ä¿®æ¹ State åæ®µæ¥å®ç°å¤çº¿ç¨çç¬å æ¨¡å¼æè å ±äº«æ¨¡å¼ãèªå®ä¹åæ¥å¨éè¦å®ç°ä»¥ä¸æ¹æ³ï¼ReentrantLock éè¦å®ç°çæ¹æ³å¦ä¸ï¼å¹¶ä¸æ¯å ¨é¨ï¼ï¼ | æ¹æ³å | æè¿° | | :------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------- | | protected boolean isHeldExclusively() | è¯¥çº¿ç¨æ¯å¦æ£å¨ç¬å èµæºãåªæç¨å° Condition æéè¦å»å®ç°å®ã | | protected boolean tryAcquire(int arg) | ç¬å æ¹å¼ãarg 为è·åéçæ¬¡æ°ï¼å°è¯è·åèµæºï¼æååè¿å Trueï¼å¤±è´¥åè¿å Falseã | | protected boolean tryRelease(int arg) | ç¬å æ¹å¼ãarg ä¸ºéæ¾éçæ¬¡æ°ï¼å°è¯éæ¾èµæºï¼æååè¿å Trueï¼å¤±è´¥åè¿å Falseã | | protected int tryAcquireShared(int arg) | å ±äº«æ¹å¼ãarg 为è·åéçæ¬¡æ°ï¼å°è¯è·åèµæºãè´æ°è¡¨ç¤ºå¤±è´¥ï¼0 表示æåï¼ä½æ²¡æå©ä½å¯ç¨èµæºï¼æ£æ°è¡¨ç¤ºæåï¼ä¸æå©ä½èµæºã | | protected boolean tryReleaseShared(int arg) | å ±äº«æ¹å¼ãarg ä¸ºéæ¾éçæ¬¡æ°ï¼å°è¯éæ¾èµæºï¼å¦æéæ¾åå 许å¤éåç»çå¾ ç»ç¹è¿å Trueï¼å¦åè¿å Falseã | ä¸è¬æ¥è¯´ï¼èªå®ä¹åæ¥å¨è¦ä¹æ¯ç¬å æ¹å¼ï¼è¦ä¹æ¯å ±äº«æ¹å¼ï¼å®ä»¬ä¹åªéå®ç° tryAcquire-tryReleaseãtryAcquireShared-tryReleaseShared ä¸çä¸ç§å³å¯ãAQS 乿¯æèªå®ä¹åæ¥å¨åæ¶å®ç°ç¬å åå ±äº«ä¸¤ç§æ¹å¼ï¼å¦ ReentrantReadWriteLockãReentrantLock æ¯ç¬å éï¼æä»¥å®ç°äº tryAcquire-tryReleaseã 以éå ¬å¹³é为ä¾ï¼è¿é主è¦éè¿°ä¸ä¸éå ¬å¹³éä¸ AQS ä¹é´æ¹æ³çå ³èä¹å¤ï¼å ·ä½æ¯ä¸å¤æ ¸å¿æ¹æ³çä½ç¨ä¼å¨æç« åé¢è¯¦ç»è¿è¡éè¿°ã  > ð ä¿®æ£ï¼åè§ï¼[issue#1761](https://github.com/Snailclimb/JavaGuide/issues/1761)ï¼: å¾ä¸çä¸å¤å°é误ï¼(AQS)CAS ä¿®æ¹å ±äº«èµæº State æåä¹ååºè¯¥æ¯è·åéæå(éå ¬å¹³é)ã > > 对åºçæºç å¦ä¸ï¼ > > ```java > final boolean nonfairTryAcquire(int acquires) { > final Thread current = Thread.currentThread();//è·åå½åçº¿ç¨ > int c = getState(); > if (c == 0) { > if (compareAndSetState(0, acquires)) {//CASæ¢é > 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; > } > ``` 为äºå¸®å©å¤§å®¶çè§£ ReentrantLock å AQS ä¹é´æ¹æ³ç交äºè¿ç¨ï¼ä»¥éå ¬å¹³é为ä¾ï¼æä»¬å°å éåè§£éçäº¤äºæµç¨åç¬æåºæ¥å¼ºè°ä¸ä¸ï¼ä»¥ä¾¿äºå¯¹åç»å 容ççè§£ã  å éï¼ - éè¿ ReentrantLock çå éæ¹æ³ Lock è¿è¡å éæä½ã - ä¼è°ç¨å°å é¨ç±» Sync ç Lock æ¹æ³ï¼ç±äº Sync#lock æ¯æ½è±¡æ¹æ³ï¼æ ¹æ® ReentrantLock åå§åéæ©çå ¬å¹³éåéå ¬å¹³éï¼æ§è¡ç¸å ³å é¨ç±»ç Lock æ¹æ³ï¼æ¬è´¨ä¸é½ä¼æ§è¡ AQS ç Acquire æ¹æ³ã - AQS ç Acquire æ¹æ³ä¼æ§è¡ tryAcquire æ¹æ³ï¼ä½æ¯ç±äº tryAcquire éè¦èªå®ä¹åæ¥å¨å®ç°ï¼å æ¤æ§è¡äº ReentrantLock ä¸ç tryAcquire æ¹æ³ï¼ç±äº ReentrantLock æ¯éè¿å ¬å¹³éåéå ¬å¹³éå é¨ç±»å®ç°ç tryAcquire æ¹æ³ï¼å æ¤ä¼æ ¹æ®éç±»åä¸åï¼æ§è¡ä¸åç tryAcquireã - tryAcquire æ¯è·åéé»è¾ï¼è·å失败åï¼ä¼æ§è¡æ¡æ¶ AQS çåç»é»è¾ï¼è· ReentrantLock èªå®ä¹åæ¥å¨æ å ³ã è§£éï¼ - éè¿ ReentrantLock çè§£éæ¹æ³ Unlock è¿è¡è§£éã - Unlock ä¼è°ç¨å é¨ç±» Sync ç Release æ¹æ³ï¼è¯¥æ¹æ³ç»§æ¿äº AQSã - Release ä¸ä¼è°ç¨ tryRelease æ¹æ³ï¼tryRelease éè¦èªå®ä¹åæ¥å¨å®ç°ï¼tryRelease åªå¨ ReentrantLock ä¸ç Sync å®ç°ï¼å æ¤å¯ä»¥çåºï¼éæ¾éçè¿ç¨ï¼å¹¶ä¸åºåæ¯å¦ä¸ºå ¬å¹³éã - éæ¾æååï¼ææå¤çç± AQS æ¡æ¶å®æï¼ä¸èªå®ä¹åæ¥å¨æ å ³ã éè¿ä¸é¢çæè¿°ï¼å¤§æ¦å¯ä»¥æ»ç»åº ReentrantLock å éè§£éæ¶ API 屿 ¸å¿æ¹æ³çæ å°å ³ç³»ã  ## 3 éè¿ ReentrantLock çè§£ AQS ReentrantLock ä¸å ¬å¹³éåéå ¬å¹³éå¨åºå±æ¯ç¸åçï¼è¿é以éå ¬å¹³é为ä¾è¿è¡åæã å¨éå ¬å¹³éä¸ï¼æä¸æ®µè¿æ ·ç代ç ï¼ ```java // java.util.concurrent.locks.ReentrantLock static final class NonfairSync extends Sync { ... final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } ... } ``` çä¸ä¸è¿ä¸ª Acquire æ¯æä¹åçï¼ ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); } ``` åçä¸ä¸ tryAcquire æ¹æ³ï¼ ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer protected boolean tryAcquire(int arg) { throw new UnsupportedOperationException(); } ``` å¯ä»¥çåºï¼è¿éåªæ¯ AQS çç®åå®ç°ï¼å ·ä½è·åéçå®ç°æ¹æ³æ¯ç±åèªçå ¬å¹³éåéå ¬å¹³éåç¬å®ç°çï¼ä»¥ ReentrantLock 为ä¾ï¼ãå¦æè¯¥æ¹æ³è¿åäº Trueï¼å说æå½å线ç¨è·åéæåï¼å°±ä¸ç¨å¾åæ§è¡äºï¼å¦æè·å失败ï¼å°±éè¦å å ¥å°çå¾ éåä¸ãä¸é¢ä¼è¯¦ç»è§£éçº¿ç¨æ¯ä½æ¶ä»¥åææ ·è¢«å å ¥è¿çå¾ éåä¸çã ### 3.1 线ç¨å å ¥çå¾ éå #### 3.1.1 å å ¥éåçæ¶æº å½æ§è¡ Acquire(1)æ¶ï¼ä¼éè¿ tryAcquire è·åéãå¨è¿ç§æ åµä¸ï¼å¦æè·åé失败ï¼å°±ä¼è°ç¨ addWaiter å å ¥å°çå¾ éåä¸å»ã #### 3.1.2 å¦ä½å å ¥éå è·åé失败åï¼ä¼æ§è¡ addWaiter(Node.EXCLUSIVE)å å ¥çå¾ éåï¼å ·ä½å®ç°æ¹æ³å¦ä¸ï¼ ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer private Node addWaiter(Node mode) { Node node = new Node(Thread.currentThread(), mode); // Try the fast path of enq; backup to full enq on failure Node pred = tail; if (pred != null) { node.prev = pred; if (compareAndSetTail(pred, node)) { pred.next = node; return node; } } enq(node); return node; } private final boolean compareAndSetTail(Node expect, Node update) { return unsafe.compareAndSwapObject(this, tailOffset, expect, update); } ``` 主è¦çæµç¨å¦ä¸ï¼ - éè¿å½åç线ç¨å鿍¡å¼æ°å»ºä¸ä¸ªèç¹ã - Pred æéæåå°¾èç¹ Tailã - å° New ä¸ Node ç Prev æéæå Predã - éè¿ compareAndSetTail æ¹æ³ï¼å®æå°¾èç¹ç设置ãè¿ä¸ªæ¹æ³ä¸»è¦æ¯å¯¹ tailOffset å Expect è¿è¡æ¯è¾ï¼å¦æ tailOffset ç Node å Expect ç Node å°åæ¯ç¸åçï¼é£ä¹è®¾ç½® Tail çå¼ä¸º Update çå¼ã ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer static { try { stateOffset = unsafe.objectFieldOffset(AbstractQueuedSynchronizer.class.getDeclaredField("state")); headOffset = unsafe.objectFieldOffset(AbstractQueuedSynchronizer.class.getDeclaredField("head")); tailOffset = unsafe.objectFieldOffset(AbstractQueuedSynchronizer.class.getDeclaredField("tail")); waitStatusOffset = unsafe.objectFieldOffset(Node.class.getDeclaredField("waitStatus")); nextOffset = unsafe.objectFieldOffset(Node.class.getDeclaredField("next")); } catch (Exception ex) { throw new Error(ex); } } ``` ä» AQS çéæä»£ç åå¯ä»¥çåºï¼é½æ¯è·åä¸ä¸ªå¯¹è±¡ç屿§ç¸å¯¹äºè¯¥å¯¹è±¡å¨å åå½ä¸çåç§»éï¼è¿æ ·æä»¬å°±å¯ä»¥æ ¹æ®è¿ä¸ªåç§»éå¨å¯¹è±¡å åå½ä¸æ¾å°è¿ä¸ªå±æ§ãtailOffset æçæ¯ tail 对åºçåç§»éï¼æä»¥è¿ä¸ªæ¶åä¼å° new åºæ¥ç Node 置为å½åéåçå°¾èç¹ãåæ¶ï¼ç±äºæ¯ååé¾è¡¨ï¼ä¹éè¦å°åä¸ä¸ªèç¹æåå°¾èç¹ã - 妿 Pred æéæ¯ Nullï¼è¯´æçå¾ éå䏿²¡æå ç´ ï¼ï¼æè å½å Pred æéå Tail æåçä½ç½®ä¸åï¼è¯´æè¢«å«ç线ç¨å·²ç»ä¿®æ¹ï¼ï¼å°±éè¦çä¸ä¸ Enq çæ¹æ³ã ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer private Node enq(final Node node) { for (;;) { Node t = tail; if (t == null) { // Must initialize if (compareAndSetHead(new Node())) tail = head; } else { node.prev = t; if (compareAndSetTail(t, node)) { t.next = node; return t; } } } } ``` å¦ææ²¡æè¢«åå§åï¼éè¦è¿è¡åå§åä¸ä¸ªå¤´ç»ç¹åºæ¥ãä½è¯·æ³¨æï¼åå§åç头ç»ç¹å¹¶ä¸æ¯å½å线ç¨èç¹ï¼èæ¯è°ç¨äºæ åæé 彿°çèç¹ã妿ç»åäºåå§åæè å¹¶å导è´éå䏿å ç´ ï¼åä¸ä¹åçæ¹æ³ç¸åãå ¶å®ï¼addWaiter å°±æ¯ä¸ä¸ªå¨å端é¾è¡¨æ·»å å°¾èç¹çæä½ï¼éè¦æ³¨æçæ¯ï¼å端é¾è¡¨ç头ç»ç¹æ¯ä¸ä¸ªæ åæé 彿°ç头ç»ç¹ã æ»ç»ä¸ä¸ï¼çº¿ç¨è·åéçæ¶åï¼è¿ç¨å¤§ä½å¦ä¸ï¼ 1ã彿²¡æçº¿ç¨è·åå°éæ¶ï¼çº¿ç¨ 1 è·åéæåã 2ãçº¿ç¨ 2 ç³è¯·éï¼ä½æ¯éè¢«çº¿ç¨ 1 å æã  3ã妿åæçº¿ç¨è¦è·åéï¼ä¾æ¬¡å¨éåä¸å¾åæéå³å¯ã åå°ä¸è¾¹ç代ç ï¼hasQueuedPredecessors æ¯å ¬å¹³éå 鿶夿çå¾ éå䏿¯å¦å卿æèç¹çæ¹æ³ã妿è¿å Falseï¼è¯´æå½å线ç¨å¯ä»¥äºåå ±äº«èµæºï¼å¦æè¿å Trueï¼è¯´æéåä¸å卿æèç¹ï¼å½å线ç¨å¿ é¡»å å ¥å°çå¾ éåä¸ã ```java // java.util.concurrent.locks.ReentrantLock 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()); } ``` çå°è¿éï¼æä»¬çè§£ä¸ä¸ h != t && ((s = h.next) == null || s.thread != Thread.currentThread());为ä»ä¹è¦å¤æç头ç»ç¹çä¸ä¸ä¸ªèç¹ï¼ç¬¬ä¸ä¸ªèç¹å¨åçæ°æ®æ¯ä»ä¹ï¼ > ååé¾è¡¨ä¸ï¼ç¬¬ä¸ä¸ªèç¹ä¸ºèèç¹ï¼å ¶å®å¹¶ä¸åå¨ä»»ä½ä¿¡æ¯ï¼åªæ¯å ä½ãçæ£ç第ä¸ä¸ªææ°æ®çèç¹ï¼æ¯å¨ç¬¬äºä¸ªèç¹å¼å§çãå½ h != t æ¶ï¼å¦æ(s = h.next) == nullï¼çå¾ éåæ£å¨æçº¿ç¨è¿è¡åå§åï¼ä½åªæ¯è¿è¡å°äº Tail æå Headï¼æ²¡æå° Head æå Tailï¼æ¤æ¶éå䏿å ç´ ï¼éè¦è¿å Trueï¼è¿åå ·ä½è§ä¸è¾¹ä»£ç åæï¼ã 妿(s = h.next) != nullï¼è¯´ææ¤æ¶éåä¸è³å°æä¸ä¸ªææèç¹ãå¦ææ¤æ¶ s.thread == Thread.currentThread()ï¼è¯´æçå¾ éåç第ä¸ä¸ªææèç¹ä¸ç线ç¨ä¸å½å线ç¨ç¸åï¼é£ä¹å½åçº¿ç¨æ¯å¯ä»¥è·åèµæºçï¼å¦æ s.thread != Thread.currentThread()ï¼è¯´æçå¾ éåç第ä¸ä¸ªææèç¹çº¿ç¨ä¸å½å线ç¨ä¸åï¼å½å线ç¨å¿ é¡»å å ¥è¿çå¾ éåã ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer#enq if (t == null) { // Must initialize if (compareAndSetHead(new Node())) tail = head; } else { node.prev = t; if (compareAndSetTail(t, node)) { t.next = node; return t; } } ``` èç¹å ¥é䏿¯ååæä½ï¼æä»¥ä¼åºç°çæç head != tailï¼æ¤æ¶ Tail æåæåä¸ä¸ªèç¹ï¼èä¸ Tail æå Headã妿 Head 没ææå Tailï¼å¯è§ 5ã6ã7 è¡ï¼ï¼è¿ç§æ åµä¸ä¹éè¦å°ç¸å ³çº¿ç¨å å ¥éåä¸ãæä»¥è¿åä»£ç æ¯ä¸ºäºè§£å³æç«¯æ åµä¸çå¹¶åé®é¢ã #### 3.1.3 çå¾ éåä¸çº¿ç¨åºéåæ¶æº åå°æåçæºç ï¼ ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); } ``` ä¸æè§£éäº addWaiter æ¹æ³ï¼è¿ä¸ªæ¹æ³å ¶å®å°±æ¯æå¯¹åºç线ç¨ä»¥ Node çæ°æ®ç»æå½¢å¼å å ¥å°å端éåéï¼è¿åçæ¯ä¸ä¸ªå å«è¯¥çº¿ç¨ç Nodeãèè¿ä¸ª Node ä¼ä½ä¸ºåæ°ï¼è¿å ¥å° acquireQueued æ¹æ³ä¸ãacquireQueued æ¹æ³å¯ä»¥å¯¹æéä¸ç线ç¨è¿è¡âè·éâæä½ã æ»çæ¥è¯´ï¼ä¸ä¸ªçº¿ç¨è·åé失败äºï¼è¢«æ¾å ¥çå¾ éåï¼acquireQueued 伿æ¾å ¥éåä¸ç线ç¨ä¸æå»è·åéï¼ç´å°è·åæåæè ä¸åéè¦è·åï¼ä¸æï¼ã ä¸é¢æä»¬ä»â使¶åºéåï¼âåâå¦ä½åºéåï¼â两个æ¹åæ¥åæä¸ä¸ acquireQueued æºç ï¼ ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer final boolean acquireQueued(final Node node, int arg) { // æ è®°æ¯å¦æåæ¿å°èµæº boolean failed = true; try { // æ è®°çå¾ è¿ç¨ä¸æ¯å¦ä¸æè¿ boolean interrupted = false; // å¼å§èªæï¼è¦ä¹è·åéï¼è¦ä¹ä¸æ for (;;) { // è·åå½åèç¹çå驱èç¹ final Node p = node.predecessor(); // 妿pæ¯å¤´ç»ç¹ï¼è¯´æå½åèç¹å¨ç宿°æ®éåçé¦é¨ï¼å°±å°è¯è·åéï¼å«å¿äºå¤´ç»ç¹æ¯èèç¹ï¼ if (p == head && tryAcquire(arg)) { // è·åéæåï¼å¤´æéç§»å¨å°å½ånode setHead(node); p.next = null; // help GC failed = false; return interrupted; } // 说æp为头èç¹ä¸å½å没æè·åå°éï¼å¯è½æ¯éå ¬å¹³é被æ¢å äºï¼æè æ¯pä¸ä¸ºå¤´ç»ç¹ï¼è¿ä¸ªæ¶åå°±è¦å¤æå½ånodeæ¯å¦è¦è¢«é»å¡ï¼è¢«é»å¡æ¡ä»¶ï¼å驱èç¹çwaitStatus为-1ï¼ï¼é²æ¢æ éå¾ªç¯æµªè´¹èµæºãå ·ä½ä¸¤ä¸ªæ¹æ³ä¸é¢ç»ç»åæ if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } finally { if (failed) cancelAcquire(node); } } ``` 注ï¼setHead æ¹æ³æ¯æå½åèç¹ç½®ä¸ºèèç¹ï¼ä½å¹¶æ²¡æä¿®æ¹ waitStatusï¼å ä¸ºå®æ¯ä¸ç´éè¦ç¨çæ°æ®ã ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer private void setHead(Node node) { head = node; node.thread = null; node.prev = null; } // java.util.concurrent.locks.AbstractQueuedSynchronizer // é å驱èç¹å¤æå½åçº¿ç¨æ¯å¦åºè¯¥è¢«é»å¡ private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { // è·å头ç»ç¹çèç¹ç¶æ int ws = pred.waitStatus; // 说æå¤´ç»ç¹å¤äºå¤éç¶æ if (ws == Node.SIGNAL) return true; // éè¿æä¸¾å¼æä»¬ç¥éwaitStatus>0æ¯åæ¶ç¶æ if (ws > 0) { do { // 循ç¯å忥æ¾åæ¶èç¹ï¼æåæ¶èç¹ä»éåä¸åé¤ node.prev = pred = pred.prev; } while (pred.waitStatus > 0); pred.next = node; } else { // 设置åä»»èç¹çå¾ ç¶æä¸ºSIGNAL compareAndSetWaitStatus(pred, ws, Node.SIGNAL); } return false; } ``` parkAndCheckInterrupt 主è¦ç¨äºæèµ·å½å线ç¨ï¼é»å¡è°ç¨æ ï¼è¿åå½å线ç¨çä¸æç¶æã ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer private final boolean parkAndCheckInterrupt() { LockSupport.park(this); return Thread.interrupted(); } ``` ä¸è¿°æ¹æ³çæµç¨å¾å¦ä¸ï¼  ä»ä¸å¾å¯ä»¥çåºï¼è·³åºå½å循ç¯çæ¡ä»¶æ¯å½âåç½®èç¹æ¯å¤´ç»ç¹ï¼ä¸å½å线ç¨è·åéæåâã为äºé²æ¢å æ»å¾ªç¯å¯¼è´ CPU èµæºè¢«æµªè´¹ï¼æä»¬ä¼å¤æåç½®èç¹çç¶ææ¥å³å®æ¯å¦è¦å°å½åçº¿ç¨æèµ·ï¼å ·ä½æèµ·æµç¨ç¨æµç¨å¾è¡¨ç¤ºå¦ä¸ï¼shouldParkAfterFailedAcquire æµç¨ï¼ï¼  ä»éåä¸éæ¾èç¹ççèææ¶äºï¼é£ä¹åææ°é®é¢äºï¼ - shouldParkAfterFailedAcquire ä¸åæ¶èç¹æ¯æä¹çæçå¢ï¼ä»ä¹æ¶å伿ä¸ä¸ªèç¹ç waitStatus 设置为-1ï¼ - æ¯å¨ä»ä¹æ¶é´éæ¾èç¹éç¥å°è¢«æèµ·ç线ç¨å¢ï¼ ### 3.2 CANCELLED ç¶æèç¹çæ acquireQueued æ¹æ³ä¸ç Finally 代ç ï¼ ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer final boolean acquireQueued(final Node node, int arg) { boolean failed = true; try { ... for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { ... failed = false; ... } ... } finally { if (failed) cancelAcquire(node); } } ``` éè¿ cancelAcquire æ¹æ³ï¼å° Node çç¶ææ 记为 CANCELLEDãæ¥ä¸æ¥ï¼æä»¬éè¡æ¥åæè¿ä¸ªæ¹æ³çåçï¼ ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer private void cancelAcquire(Node node) { // å°æ æèç¹è¿æ»¤ if (node == null) return; // 设置该èç¹ä¸å ³èä»»ä½çº¿ç¨ï¼ä¹å°±æ¯èèç¹ node.thread = null; Node pred = node.prev; // éè¿å驱èç¹ï¼è·³è¿åæ¶ç¶æçnode while (pred.waitStatus > 0) node.prev = pred = pred.prev; // è·åè¿æ»¤åçå驱èç¹çåç»§èç¹ Node predNext = pred.next; // æå½ånodeçç¶æè®¾ç½®ä¸ºCANCELLED node.waitStatus = Node.CANCELLED; // 妿å½åèç¹æ¯å°¾èç¹ï¼å°ä»åå¾åç第ä¸ä¸ªéåæ¶ç¶æçèç¹è®¾ç½®ä¸ºå°¾èç¹ // æ´æ°å¤±è´¥çè¯ï¼åè¿å ¥elseï¼å¦ææ´æ°æåï¼å°tailçåç»§èç¹è®¾ç½®ä¸ºnull if (node == tail && compareAndSetTail(node, pred)) { compareAndSetNext(pred, predNext, null); } else { int ws; // 妿å½åèç¹ä¸æ¯headçåç»§èç¹ï¼1:夿å½åèç¹å驱èç¹çæ¯å¦ä¸ºSIGNALï¼2:妿䏿¯ï¼åæå驱èç¹è®¾ç½®ä¸ºSINGALçæ¯å¦æå // 妿1å2䏿ä¸ä¸ªä¸ºtrueï¼å夿å½åèç¹ççº¿ç¨æ¯å¦ä¸ºnull // 妿ä¸è¿°æ¡ä»¶é½æ»¡è¶³ï¼æå½åèç¹çå驱èç¹çåç»§æéæåå½åèç¹çåç»§èç¹ if (pred != head && ((ws = pred.waitStatus) == Node.SIGNAL || (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) && pred.thread != null) { Node next = node.next; if (next != null && next.waitStatus <= 0) compareAndSetNext(pred, predNext, next); } else { // 妿å½åèç¹æ¯headçåç»§èç¹ï¼æè ä¸è¿°æ¡ä»¶ä¸æ»¡è¶³ï¼é£å°±å¤éå½åèç¹çåç»§èç¹ unparkSuccessor(node); } node.next = node; // help GC } } ``` å½åçæµç¨ï¼ - è·åå½åèç¹çå驱èç¹ï¼å¦æå驱èç¹çç¶ææ¯ CANCELLEDï¼é£å°±ä¸ç´å¾åéåï¼æ¾å°ç¬¬ä¸ä¸ª waitStatus <= 0 çèç¹ï¼å°æ¾å°ç Pred èç¹åå½å Node å ³èï¼å°å½å Node 设置为 CANCELLEDã - æ ¹æ®å½åèç¹çä½ç½®ï¼èè以ä¸ä¸ç§æ åµï¼ (1) å½åèç¹æ¯å°¾èç¹ã (2) å½åèç¹æ¯ Head çåç»§èç¹ã (3) å½åèç¹ä¸æ¯ Head çåç»§èç¹ï¼ä¹ä¸æ¯å°¾èç¹ã æ ¹æ®ä¸è¿°ç¬¬äºæ¡ï¼æä»¬æ¥åææ¯ä¸ç§æ åµçæµç¨ã å½åèç¹æ¯å°¾èç¹ã  å½åèç¹æ¯ Head çåç»§èç¹ã  å½åèç¹ä¸æ¯ Head çåç»§èç¹ï¼ä¹ä¸æ¯å°¾èç¹ã  éè¿ä¸é¢çæµç¨ï¼æä»¬å¯¹äº CANCELLED èç¹ç¶æç产çåååå·²ç»æäºå¤§è´çäºè§£ï¼ä½æ¯ä¸ºä»ä¹ææçåå齿¯å¯¹ Next æéè¿è¡äºæä½ï¼è没æå¯¹ Prev æéè¿è¡æä½å¢ï¼ä»ä¹æ åµä¸ä¼å¯¹ Prev æéè¿è¡æä½ï¼ > æ§è¡ cancelAcquire çæ¶åï¼å½åèç¹çåç½®èç¹å¯è½å·²ç»ä»éåä¸åºå»äºï¼å·²ç»æ§è¡è¿ Try 代ç åä¸ç shouldParkAfterFailedAcquire æ¹æ³äºï¼ï¼å¦ææ¤æ¶ä¿®æ¹ Prev æéï¼æå¯è½ä¼å¯¼è´ Prev æåå¦ä¸ä¸ªå·²ç»ç§»é¤éåç Nodeï¼å æ¤è¿ååå Prev æéä¸å®å ¨ã shouldParkAfterFailedAcquire æ¹æ³ä¸ï¼ä¼æ§è¡ä¸é¢ç代ç ï¼å ¶å®å°±æ¯å¨å¤ç Prev æéãshouldParkAfterFailedAcquire æ¯è·åéå¤±è´¥çæ åµä¸æä¼æ§è¡ï¼è¿å ¥è¯¥æ¹æ³åï¼è¯´æå ±äº«èµæºå·²è¢«è·åï¼å½åèç¹ä¹åçèç¹é½ä¸ä¼åºç°ååï¼å æ¤è¿ä¸ªæ¶ååæ´ Prev æéæ¯è¾å®å ¨ã > > ```java > do { > node.prev = pred = pred.prev; > } while (pred.waitStatus > 0); > ``` ### 3.3 å¦ä½è§£é æä»¬å·²ç»åæäºå éè¿ç¨ä¸çåºæ¬æµç¨ï¼æ¥ä¸æ¥å对解éçåºæ¬æµç¨è¿è¡åæãç±äº ReentrantLock å¨è§£éçæ¶åï¼å¹¶ä¸åºåå ¬å¹³éåéå ¬å¹³éï¼æä»¥æä»¬ç´æ¥çè§£éçæºç ï¼ ```java // java.util.concurrent.locks.ReentrantLock public void unlock() { sync.release(1); } ``` å¯ä»¥çå°ï¼æ¬è´¨éæ¾éçå°æ¹ï¼æ¯éè¿æ¡æ¶æ¥å®æçã ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer public final boolean release(int arg) { if (tryRelease(arg)) { Node h = head; if (h != null && h.waitStatus != 0) unparkSuccessor(h); return true; } return false; } ``` å¨ ReentrantLock éé¢çå ¬å¹³éåéå ¬å¹³éçç¶ç±» Sync å®ä¹äºå¯éå ¥éçéæ¾éæºå¶ã ```java // java.util.concurrent.locks.ReentrantLock.Sync // æ¹æ³è¿åå½å鿝䏿¯æ²¡æè¢«çº¿ç¨ææ protected final boolean tryRelease(int releases) { // åå°å¯éå ¥æ¬¡æ° int c = getState() - releases; // å½å线ç¨ä¸æ¯ææéç线ç¨ï¼æåºå¼å¸¸ if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); boolean free = false; // 妿ææçº¿ç¨å ¨é¨éæ¾ï¼å°å½åç¬å éææçº¿ç¨è®¾ç½®ä¸ºnullï¼å¹¶æ´æ°state if (c == 0) { free = true; setExclusiveOwnerThread(null); } setState(c); return free; } ``` æä»¬æ¥è§£éä¸è¿°æºç ï¼ ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer public final boolean release(int arg) { // ä¸è¾¹èªå®ä¹çtryRelease妿è¿åtrueï¼è¯´æè¯¥é没æè¢«ä»»ä½çº¿ç¨ææ if (tryRelease(arg)) { // è·å头ç»ç¹ Node h = head; // 头ç»ç¹ä¸ä¸ºç©ºå¹¶ä¸å¤´ç»ç¹çwaitStatus䏿¯åå§åèç¹æ åµï¼è§£é¤çº¿ç¨æèµ·ç¶æ if (h != null && h.waitStatus != 0) unparkSuccessor(h); return true; } return false; } ``` è¿éç夿æ¡ä»¶ä¸ºä»ä¹æ¯ h != null && h.waitStatus != 0ï¼ > h == null Head è¿æ²¡åå§åãåå§æ åµä¸ï¼head == nullï¼ç¬¬ä¸ä¸ªèç¹å ¥éï¼Head ä¼è¢«åå§åä¸ä¸ªèæèç¹ãæä»¥è¯´ï¼è¿éå¦æè¿æ²¡æ¥å¾åå ¥éï¼å°±ä¼åºç° head == null çæ åµã > > h != null && waitStatus == 0 表æåç»§èç¹å¯¹åºç线ç¨ä»å¨è¿è¡ä¸ï¼ä¸éè¦å¤éã > > h != null && waitStatus < 0 表æåç»§èç¹å¯è½è¢«é»å¡äºï¼éè¦å¤éã åçä¸ä¸ unparkSuccessor æ¹æ³ï¼ ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer private void unparkSuccessor(Node node) { // è·å头ç»ç¹waitStatus int ws = node.waitStatus; if (ws < 0) compareAndSetWaitStatus(node, ws, 0); // è·åå½åèç¹çä¸ä¸ä¸ªèç¹ Node s = node.next; // 妿ä¸ä¸ªèç¹æ¯nullæè ä¸ä¸ªèç¹è¢«cancelledï¼å°±æ¾å°éåæå¼å§çécancelledçèç¹ if (s == null || s.waitStatus > 0) { s = null; // å°±ä»å°¾é¨èç¹å¼å§æ¾ï¼å°éé¦ï¼æ¾å°éå第ä¸ä¸ªwaitStatus<0çèç¹ã for (Node t = tail; t != null && t != node; t = t.prev) if (t.waitStatus <= 0) s = t; } // 妿å½åèç¹çä¸ä¸ªèç¹ä¸ä¸ºç©ºï¼èä¸ç¶æ<=0ï¼å°±æå½åèç¹unpark if (s != null) LockSupport.unpark(s.thread); } ``` 为ä»ä¹è¦ä»åå¾åæ¾ç¬¬ä¸ä¸ªé Cancelled çèç¹å¢ï¼åå å¦ä¸ã ä¹åç addWaiter æ¹æ³ï¼ ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer private Node addWaiter(Node mode) { Node node = new Node(Thread.currentThread(), mode); // Try the fast path of enq; backup to full enq on failure Node pred = tail; if (pred != null) { node.prev = pred; if (compareAndSetTail(pred, node)) { pred.next = node; return node; } } enq(node); return node; } ``` æä»¬ä»è¿éå¯ä»¥çå°ï¼èç¹å ¥é并䏿¯ååæä½ï¼ä¹å°±æ¯è¯´ï¼node.prev = pred; compareAndSetTail(pred, node) è¿ä¸¤ä¸ªå°æ¹å¯ä»¥çä½ Tail å ¥éçååæä½ï¼ä½æ¯æ¤æ¶ pred.next = node;è¿æ²¡æ§è¡ï¼å¦æè¿ä¸ªæ¶åæ§è¡äº unparkSuccessor æ¹æ³ï¼å°±æ²¡åæ³ä»åå¾åæ¾äºï¼æä»¥éè¦ä»åå¾åæ¾ãè¿æä¸ç¹åå ï¼å¨äº§ç CANCELLED ç¶æèç¹çæ¶åï¼å æå¼çæ¯ Next æéï¼Prev æéå¹¶æªæå¼ï¼å æ¤ä¹æ¯å¿ é¡»è¦ä»åå¾åéåæè½å¤éåå®å ¨é¨ç Nodeã ç»¼ä¸æè¿°ï¼å¦ææ¯ä»åå¾åæ¾ï¼ç±äºæç«¯æ åµä¸å ¥éçéååæä½å CANCELLED èç¹äº§çè¿ç¨ä¸æå¼ Next æéçæä½ï¼å¯è½ä¼å¯¼è´æ æ³éåææçèç¹ãæä»¥ï¼å¤é对åºç线ç¨åï¼å¯¹åºç线ç¨å°±ä¼ç»§ç»å¾ä¸æ§è¡ãç»§ç»æ§è¡ acquireQueued æ¹æ³ä»¥åï¼ä¸æå¦ä½å¤çï¼ ### 3.4 䏿æ¢å¤åçæ§è¡æµç¨ å¤éåï¼ä¼æ§è¡ return Thread.interrupted();ï¼è¿ä¸ªå½æ°è¿åçæ¯å½åæ§è¡çº¿ç¨çä¸æç¶æï¼å¹¶æ¸ é¤ã ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer private final boolean parkAndCheckInterrupt() { LockSupport.park(this); return Thread.interrupted(); } ``` ååå° acquireQueued 代ç ï¼å½ parkAndCheckInterrupt è¿å True æè False çæ¶åï¼interrupted çå¼ä¸åï¼ä½é½ä¼æ§è¡ä¸æ¬¡å¾ªç¯ã妿è¿ä¸ªæ¶åè·åéæåï¼å°±ä¼æå½å interrupted è¿åã ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer final boolean acquireQueued(final Node node, int arg) { boolean failed = true; try { boolean interrupted = false; for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC failed = false; return interrupted; } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } finally { if (failed) cancelAcquire(node); } } ``` 妿 acquireQueued 为 Trueï¼å°±ä¼æ§è¡ selfInterrupt æ¹æ³ã ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer static void selfInterrupt() { Thread.currentThread().interrupt(); } ``` è¯¥æ¹æ³å ¶å®æ¯ä¸ºäºä¸æçº¿ç¨ãä½ä¸ºä»ä¹è·åäºé以åè¿è¦ä¸æçº¿ç¨å¢ï¼è¿é¨åå±äº Java æä¾çåä½å¼ä¸æç¥è¯å å®¹ï¼æå ´è¶£åå¦å¯ä»¥æ¥é ä¸ä¸ãè¿éç®åä»ç»ä¸ä¸ï¼ 1. å½ä¸æçº¿ç¨è¢«å¤éæ¶ï¼å¹¶ä¸ç¥é被å¤éçåå ï¼å¯è½æ¯å½å线ç¨å¨çå¾ ä¸è¢«ä¸æï¼ä¹å¯è½æ¯éæ¾äºé以å被å¤éãå æ¤æä»¬éè¿ Thread.interrupted()æ¹æ³æ£æ¥ä¸ææ è®°ï¼è¯¥æ¹æ³è¿åäºå½å线ç¨çä¸æç¶æï¼å¹¶å°å½å线ç¨ç䏿æ è¯è®¾ç½®ä¸º Falseï¼ï¼å¹¶è®°å½ä¸æ¥ï¼å¦æåç°è¯¥çº¿ç¨è¢«ä¸æè¿ï¼å°±å䏿䏿¬¡ã 2. 线ç¨å¨çå¾ èµæºçè¿ç¨ä¸è¢«å¤éï¼å¤éåè¿æ¯ä¼ä¸æå°å»å°è¯è·åéï¼ç´å°æ¢å°é为æ¢ãä¹å°±æ¯è¯´ï¼å¨æ´ä¸ªæµç¨ä¸ï¼å¹¶ä¸ååºä¸æï¼åªæ¯è®°å½ä¸æè®°å½ãæåæ¢å°éè¿åäºï¼é£ä¹å¦æè¢«ä¸æè¿çè¯ï¼å°±éè¦è¡¥å 䏿¬¡ä¸æã è¿éçå¤çæ¹å¼ä¸»è¦æ¯è¿ç¨çº¿ç¨æ± ä¸åºæ¬è¿ä½åå Worder ä¸ç runWorkerï¼éè¿ Thread.interrupted()è¿è¡é¢å¤ç夿å¤çï¼æå ´è¶£çåå¦å¯ä»¥çä¸ ThreadPoolExecutor æºç ã ### 3.5 å°ç» æä»¬å¨ 1.3 å°è䏿åºäºä¸äºé®é¢ï¼ç°å¨æ¥åçä¸ä¸ã > Qï¼æä¸ªçº¿ç¨è·åé失败çåç»æµç¨æ¯ä»ä¹å¢ï¼ > > Aï¼åå¨æç§æéçåæºå¶ï¼çº¿ç¨ç»§ç»çå¾ ï¼ä»ç¶ä¿çè·åéçå¯è½ï¼è·åéæµç¨ä»å¨ç»§ç»ã > > Qï¼æ¢ç¶è¯´å°äºæéçåæºå¶ï¼é£ä¹å°±ä¸å®ä¼ææç§éåå½¢æï¼è¿æ ·çé忝ä»ä¹æ°æ®ç»æå¢ï¼ > > Aï¼æ¯ CLH åä½ç FIFO å端éåã > > Qï¼å¤äºæéçåæºå¶ä¸ç线ç¨ï¼ä»ä¹æ¶åå¯ä»¥ææºä¼è·åéå¢ï¼ > > Aï¼å¯ä»¥è¯¦ç»çä¸ 2.3.1.3 å°èã > > Qï¼å¦æå¤äºæéçåæºå¶ä¸ç线ç¨ä¸ç´æ æ³è·åéï¼éè¦ä¸ç´çå¾ ä¹ï¼è¿æ¯æå«ççç¥æ¥è§£å³è¿ä¸é®é¢ï¼ > > Aï¼çº¿ç¨æå¨èç¹çç¶æä¼åæåæ¶ç¶æï¼åæ¶ç¶æçèç¹ä¼ä»éåä¸éæ¾ï¼å ·ä½å¯è§ 2.3.2 å°èã > > Qï¼Lock 彿°éè¿ Acquire æ¹æ³è¿è¡å éï¼ä½æ¯å ·ä½æ¯å¦ä½å éçå¢ï¼ > > Aï¼AQS ç Acquire ä¼è°ç¨ tryAcquire æ¹æ³ï¼tryAcquire ç±å个èªå®ä¹åæ¥å¨å®ç°ï¼éè¿ tryAcquire 宿å éè¿ç¨ã ## 4 AQS åºç¨ ### 4.1 ReentrantLock çå¯éå ¥åºç¨ ReentrantLock çå¯éå ¥æ§æ¯ AQS å¾å¥½çåºç¨ä¹ä¸ï¼å¨äºè§£å®ä¸è¿°ç¥è¯ç¹ä»¥åï¼æä»¬å¾å®¹æå¾ç¥ ReentrantLock å®ç°å¯éå ¥çæ¹æ³ãå¨ ReentrantLock éé¢ï¼ä¸ç®¡æ¯å ¬å¹³éè¿æ¯éå ¬å¹³éï¼é½æä¸æ®µé»è¾ã å ¬å¹³éï¼ ```java // java.util.concurrent.locks.ReentrantLock.FairSync#tryAcquire 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; } ``` éå ¬å¹³éï¼ ```java // java.util.concurrent.locks.ReentrantLock.Sync#nonfairTryAcquire if (c == 0) { 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; } ``` ä»ä¸é¢è¿ä¸¤æ®µé½å¯ä»¥çå°ï¼æä¸ä¸ªåæ¥ç¶æ State æ¥æ§å¶æ´ä½å¯éå ¥çæ åµãState æ¯ Volatile 修饰çï¼ç¨äºä¿è¯ä¸å®çå¯è§æ§åæåºæ§ã ```java // java.util.concurrent.locks.AbstractQueuedSynchronizer private volatile int state; ``` æ¥ä¸æ¥ç State è¿ä¸ªå段主è¦çè¿ç¨ï¼ 1. State åå§åçæ¶å为 0ï¼è¡¨ç¤ºæ²¡æä»»ä½çº¿ç¨ææéã 2. å½æçº¿ç¨ææè¯¥éæ¶ï¼å¼å°±ä¼å¨åæ¥çåºç¡ä¸+1ï¼åä¸ä¸ªçº¿ç¨å¤æ¬¡è·å¾éæ¯ï¼å°±ä¼å¤æ¬¡+1ï¼è¿éå°±æ¯å¯éå ¥çæ¦å¿µã 3. è§£é乿¯å¯¹è¿ä¸ªå段-1ï¼ä¸ç´å° 0ï¼æ¤çº¿ç¨å¯¹ééæ¾ã ### 4.2 JUC ä¸çåºç¨åºæ¯ é¤äºä¸è¾¹ ReentrantLock çå¯éå ¥æ§çåºç¨ï¼AQS ä½ä¸ºå¹¶åç¼ç¨çæ¡æ¶ï¼ä¸ºå¾å¤å ¶ä»åæ¥å·¥å ·æä¾äºè¯å¥½çè§£å³æ¹æ¡ãä¸é¢ååºäº JUC ä¸çå ç§åæ¥å·¥å ·ï¼å¤§ä½ä»ç»ä¸ä¸ AQS çåºç¨åºæ¯ï¼ | åæ¥å·¥å · | åæ¥å·¥å ·ä¸ AQS çå ³è | | :--------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | | ReentrantLock | ä½¿ç¨ AQS ä¿åéé夿æç次æ°ãå½ä¸ä¸ªçº¿ç¨è·åéæ¶ï¼ReentrantLock è®°å½å½åè·å¾éççº¿ç¨æ è¯ï¼ç¨äºæ£æµæ¯å¦éå¤è·åï¼ä»¥åé误线ç¨è¯å¾è§£éæä½æ¶å¼å¸¸æ åµçå¤çã | | Semaphore | ä½¿ç¨ AQS åæ¥ç¶ææ¥ä¿åä¿¡å·éçå½å计æ°ãtryRelease ä¼å¢å 计æ°ï¼acquireShared ä¼åå°è®¡æ°ã | | CountDownLatch | ä½¿ç¨ AQS åæ¥ç¶ææ¥è¡¨ç¤ºè®¡æ°ã计æ°ä¸º 0 æ¶ï¼ææç Acquire æä½ï¼CountDownLatch ç await æ¹æ³ï¼æå¯ä»¥éè¿ã | | ReentrantReadWriteLock | ä½¿ç¨ AQS åæ¥ç¶æä¸ç 16 ä½ä¿ååéææçæ¬¡æ°ï¼å©ä¸ç 16 ä½ç¨äºä¿å读éçæææ¬¡æ°ã | | ThreadPoolExecutor | Worker å©ç¨ AQS åæ¥ç¶æå®ç°å¯¹ç¬å 线ç¨åéç设置ï¼tryAcquire å tryReleaseï¼ã | ### 4.3 èªå®ä¹åæ¥å·¥å · äºè§£ AQS åºæ¬åç以åï¼æç §ä¸é¢æè¯´ç AQS ç¥è¯ç¹ï¼èªå·±å®ç°ä¸ä¸ªåæ¥å·¥å ·ã ```java public class LeeLock { private static class Sync extends AbstractQueuedSynchronizer { @Override protected boolean tryAcquire (int arg) { return compareAndSetState(0, 1); } @Override protected boolean tryRelease (int arg) { setState(0); return true; } @Override protected boolean isHeldExclusively () { return getState() == 1; } } private Sync sync = new Sync(); public void lock () { sync.acquire(1); } public void unlock () { sync.release(1); } } ``` éè¿æä»¬èªå·±å®ä¹ç Lock 宿ä¸å®ç忥åè½ã ```java public class LeeMain { static int count = 0; static LeeLock leeLock = new LeeLock(); public static void main (String[] args) throws InterruptedException { Runnable runnable = new Runnable() { @Override public void run () { try { leeLock.lock(); for (int i = 0; i < 10000; i++) { count++; } } catch (Exception e) { e.printStackTrace(); } finally { leeLock.unlock(); } } }; Thread thread1 = new Thread(runnable); Thread thread2 = new Thread(runnable); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println(count); } } ``` ä¸è¿°ä»£ç æ¯æ¬¡è¿è¡ç»æé½ä¼æ¯ 20000ãéè¿ç®åçå è¡ä»£ç å°±è½å®ç°åæ¥åè½ï¼è¿å°±æ¯ AQS ç强大ä¹å¤ã ## 5 æ»ç» æä»¬æ¥å¸¸å¼åä¸ä½¿ç¨å¹¶åçåºæ¯å¤ªå¤ï¼ä½æ¯å¯¹å¹¶åå é¨çåºæ¬æ¡æ¶åçäºè§£ç人å´ä¸å¤ãç±äºç¯å¹ åå ï¼æ¬æä» ä»ç»äºå¯éå ¥é ReentrantLock çåçå AQS åçï¼å¸æè½å¤æä¸ºå¤§å®¶äºè§£ AQS å ReentrantLock ç忥å¨çâæ²é¨ç âã ## åèèµæ - Lea D. The java. util. concurrent synchronizer framework[J]. Science of Computer Programming, 2005, 58(3): 293-309. - ãJava å¹¶åç¼ç¨å®æã - [ä¸å¯ä¸è¯´ç Javaâéâäº](https://tech.meituan.com/2018/11/15/java-lock.html)