**ç®å½ï¼** - [1 AQS ç®åä»ç»](#1-aqs-ç®åä»ç») - [2 AQS åç](#2-aqs-åç) - [2.1 AQS åçæ¦è§](#21-aqs-åçæ¦è§) - [2.2 AQS å¯¹èµæºçå ±äº«æ¹å¼](#22-aqs-å¯¹èµæºçå ±äº«æ¹å¼) - [2.3 AQSåºå±ä½¿ç¨äºæ¨¡æ¿æ¹æ³æ¨¡å¼](#23-aqsåºå±ä½¿ç¨äºæ¨¡æ¿æ¹æ³æ¨¡å¼) - [3 Semaphore\(ä¿¡å·é\)-å 许å¤ä¸ªçº¿ç¨åæ¶è®¿é®](#3-semaphoreä¿¡å·é-å 许å¤ä¸ªçº¿ç¨åæ¶è®¿é®) - [4 CountDownLatch ï¼å计æ¶å¨ï¼](#4-countdownlatch-å计æ¶å¨) - [4.1 CountDownLatch çä¸ç§å ¸åç¨æ³](#41-countdownlatch-çä¸ç§å ¸åç¨æ³) - [4.2 CountDownLatch ç使ç¨ç¤ºä¾](#42-countdownlatch-ç使ç¨ç¤ºä¾) - [4.3 CountDownLatch çä¸è¶³](#43-countdownlatch-çä¸è¶³) - [4.4 CountDownLatchç¸å¸¸è§é¢è¯é¢ï¼](#44-countdownlatchç¸å¸¸è§é¢è¯é¢) - [5 CyclicBarrier\(å¾ªç¯æ æ \)](#5-cyclicbarrierå¾ªç¯æ æ ) - [5.1 CyclicBarrier çåºç¨åºæ¯](#51-cyclicbarrier-çåºç¨åºæ¯) - [5.2 CyclicBarrier ç使ç¨ç¤ºä¾](#52-cyclicbarrier-ç使ç¨ç¤ºä¾) - [5.3 CyclicBarrieråCountDownLatchçåºå«](#53-cyclicbarrieråcountdownlatchçåºå«) - [6 ReentrantLock å ReentrantReadWriteLock](#6-reentrantlock-å-reentrantreadwritelock) > 常è§é®é¢ï¼AQSåçï¼;CountDownLatchåCyclicBarrieräºè§£å,两è çåºå«æ¯ä»ä¹ï¼ç¨è¿Semaphoreåï¼ **æ¬èæç»´å¯¼å¾ï¼**  ### 1 AQS ç®åä»ç» AQSçå ¨ç§°ä¸ºï¼AbstractQueuedSynchronizerï¼ï¼è¿ä¸ªç±»å¨java.util.concurrent.lockså ä¸é¢ã  AQSæ¯ä¸ä¸ªç¨æ¥æå»ºéå忥å¨çæ¡æ¶ï¼ä½¿ç¨AQSè½ç®åä¸é«æå°æé åºåºç¨å¹¿æ³ç大éç忥å¨ï¼æ¯å¦æä»¬æå°çReentrantLockï¼Semaphoreï¼å ¶ä»ç诸å¦ReentrantReadWriteLockï¼SynchronousQueueï¼FutureTaskçççæ¯åºäºAQSçãå½ç¶ï¼æä»¬èªå·±ä¹è½å©ç¨AQSé常轻æ¾å®¹æå°æé åºç¬¦åæä»¬èªå·±éæ±ç忥å¨ã ### 2 AQS åç > å¨é¢è¯ä¸è¢«é®å°å¹¶åç¥è¯çæ¶åï¼å¤§å¤é½ä¼è¢«é®å°âè¯·ä½ è¯´ä¸ä¸èªå·±å¯¹äºAQSåçççè§£âãä¸é¢ç»å¤§å®¶ä¸ä¸ªç¤ºä¾ä¾å¤§å®¶åå ï¼é¢è¯ä¸æ¯èé¢ï¼å¤§å®¶ä¸å®è¦å å ¥èªå·±çææ³ï¼å³ä½¿å å ¥ä¸äºèªå·±çææ³ä¹è¦ä¿è¯èªå·±è½å¤éä¿çè®²åºæ¥è䏿¯èåºæ¥ã ä¸é¢å¤§é¨åå å®¹å ¶å®å¨AQS类注éä¸å·²ç»ç»åºäºï¼ä¸è¿æ¯è±è¯ççæ¯è¾ååä¸ç¹ï¼æå ´è¶£çè¯å¯ä»¥ççæºç ã #### 2.1 AQS åçæ¦è§ **AQSæ ¸å¿ææ³æ¯ï¼å¦æè¢«è¯·æ±çå ±äº«èµæºç©ºé²ï¼åå°å½å请æ±èµæºç线ç¨è®¾ç½®ä¸ºææçå·¥ä½çº¿ç¨ï¼å¹¶ä¸å°å ±äº«èµæºè®¾ç½®ä¸ºéå®ç¶æãå¦æè¢«è¯·æ±çå ±äº«èµæºè¢«å ç¨ï¼é£ä¹å°±éè¦ä¸å¥çº¿ç¨é»å¡çå¾ ä»¥å被å¤éæ¶éåé çæºå¶ï¼è¿ä¸ªæºå¶AQSæ¯ç¨CLHéåéå®ç°çï¼å³å°ææ¶è·åä¸å°éç线ç¨å å ¥å°éåä¸ã** > CLH(Craig,Landin,and Hagersten)é忝ä¸ä¸ªèæçååéåï¼èæçååéåå³ä¸åå¨éåå®ä¾ï¼ä» åå¨ç»ç¹ä¹é´çå ³èå ³ç³»ï¼ãAQSæ¯å°æ¯æ¡è¯·æ±å ±äº«èµæºç线ç¨å°è£ æä¸ä¸ªCLHééåçä¸ä¸ªç»ç¹ï¼Nodeï¼æ¥å®ç°éçåé ã ç个AQS(AbstractQueuedSynchronizer)åçå¾ï¼  AQS使ç¨ä¸ä¸ªintæååéæ¥è¡¨ç¤ºåæ¥ç¶æï¼éè¿å ç½®çFIFOé忥宿è·åèµæºçº¿ç¨çæéå·¥ä½ãAQS使ç¨CASå¯¹è¯¥åæ¥ç¶æè¿è¡ååæä½å®ç°å¯¹å ¶å¼çä¿®æ¹ã ```java private volatile int state;//å ±äº«åéï¼ä½¿ç¨volatile修饰ä¿è¯çº¿ç¨å¯è§æ§ ``` ç¶æä¿¡æ¯éè¿protectedç±»åçgetStateï¼setStateï¼compareAndSetStateè¿è¡æä½ ```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); } ``` #### 2.2 AQS å¯¹èµæºçå ±äº«æ¹å¼ **AQSå®ä¹ä¸¤ç§èµæºå ±äº«æ¹å¼** - **Exclusive**ï¼ç¬å ï¼ï¼åªæä¸ä¸ªçº¿ç¨è½æ§è¡ï¼å¦ReentrantLockãåå¯åä¸ºå ¬å¹³éåéå ¬å¹³éï¼ - å ¬å¹³éï¼æç §çº¿ç¨å¨éåä¸çæé顺åºï¼å å°è å æ¿å°é - éå ¬å¹³éï¼å½çº¿ç¨è¦è·åéæ¶ï¼æ è§éå顺åºç´æ¥å»æ¢éï¼è°æ¢å°å°±æ¯è°ç - **Share**ï¼å ±äº«ï¼ï¼å¤ä¸ªçº¿ç¨å¯åæ¶æ§è¡ï¼å¦Semaphore/CountDownLatchãSemaphoreãCountDownLatChã CyclicBarrierãReadWriteLock æä»¬é½ä¼å¨åé¢è®²å°ã ReentrantReadWriteLock å¯ä»¥çææ¯ç»åå¼ï¼å 为ReentrantReadWriteLockä¹å°±æ¯è¯»åéå 许å¤ä¸ªçº¿ç¨åæ¶å¯¹æä¸èµæºè¿è¡è¯»ã ä¸åçèªå®ä¹åæ¥å¨äºç¨å ±äº«èµæºçæ¹å¼ä¹ä¸åãèªå®ä¹åæ¥å¨å¨å®ç°æ¶åªéè¦å®ç°å ±äº«èµæº state çè·åä¸éæ¾æ¹å¼å³å¯ï¼è³äºå ·ä½çº¿ç¨çå¾ éåçç»´æ¤ï¼å¦è·åèµæºå¤±è´¥å ¥é/å¤éåºéçï¼ï¼AQSå·²ç»å¨ä¸å±å·²ç»å¸®æä»¬å®ç°å¥½äºã #### 2.3 AQSåºå±ä½¿ç¨äºæ¨¡æ¿æ¹æ³æ¨¡å¼ 忥å¨ç设计æ¯åºäºæ¨¡æ¿æ¹æ³æ¨¡å¼çï¼å¦æéè¦èªå®ä¹åæ¥å¨ä¸è¬çæ¹å¼æ¯è¿æ ·ï¼æ¨¡æ¿æ¹æ³æ¨¡å¼å¾ç»å ¸çä¸ä¸ªåºç¨ï¼ï¼ 1. 使ç¨è ç»§æ¿AbstractQueuedSynchronizerå¹¶éåæå®çæ¹æ³ãï¼è¿äºéåæ¹æ³å¾ç®åï¼æ 鿝坹äºå ±äº«èµæºstateçè·ååéæ¾ï¼ 2. å°AQSç»åå¨èªå®ä¹åæ¥ç»ä»¶çå®ç°ä¸ï¼å¹¶è°ç¨å ¶æ¨¡æ¿æ¹æ³ï¼èè¿äºæ¨¡æ¿æ¹æ³ä¼è°ç¨ä½¿ç¨è éåçæ¹æ³ã è¿åæä»¬ä»¥å¾éè¿å®ç°æ¥å£çæ¹å¼æå¾å¤§åºå«ï¼è¿æ¯æ¨¡æ¿æ¹æ³æ¨¡å¼å¾ç»å ¸çä¸ä¸ªè¿ç¨ï¼ä¸é¢ç®åçç»å¤§å®¶ä»ç»ä¸ä¸æ¨¡æ¿æ¹æ³æ¨¡å¼ï¼æ¨¡æ¿æ¹æ³æ¨¡å¼æ¯ä¸ä¸ªå¾å®¹æçè§£ç设计模å¼ä¹ä¸ã > æ¨¡æ¿æ¹æ³æ¨¡å¼æ¯åºäºâç»§æ¿âçï¼ä¸»è¦æ¯ä¸ºäºå¨ä¸æ¹å模æ¿ç»æçåæä¸å¨åç±»ä¸éæ°å®ä¹æ¨¡æ¿ä¸çå 容以å®ç°å¤ç¨ä»£ç ã举个å¾ç®åçä¾åå妿们è¦å»ä¸ä¸ªå°æ¹çæ¥éª¤æ¯ï¼è´ç¥¨`buyTicket()`->宿£`securityCheck()`->ä¹åææå·¥å ·åå®¶`ride()`->å°è¾¾ç®çå°`arrive()`ãæä»¬å¯è½ä¹åä¸åç交éå·¥å ·åå®¶æ¯å¦é£æºæè ç«è½¦ï¼æä»¥é¤äº`ride()`æ¹æ³ï¼å ¶ä»æ¹æ³çå®ç°å ä¹ç¸åãæä»¬å¯ä»¥å®ä¹ä¸ä¸ªå å«äºè¿äºæ¹æ³çæ½è±¡ç±»ï¼ç¶åç¨æ·æ ¹æ®èªå·±çéè¦ç»§æ¿è¯¥æ½è±¡ç±»ç¶åä¿®æ¹ `ride()`æ¹æ³ã **AQS使ç¨äºæ¨¡æ¿æ¹æ³æ¨¡å¼ï¼èªå®ä¹åæ¥å¨æ¶éè¦éåä¸é¢å 个AQSæä¾çæ¨¡æ¿æ¹æ³ï¼** ```java isHeldExclusively()//è¯¥çº¿ç¨æ¯å¦æ£å¨ç¬å èµæºãåªæç¨å°conditionæéè¦å»å®ç°å®ã tryAcquire(int)//ç¬å æ¹å¼ãå°è¯è·åèµæºï¼æååè¿åtrueï¼å¤±è´¥åè¿åfalseã tryRelease(int)//ç¬å æ¹å¼ãå°è¯éæ¾èµæºï¼æååè¿åtrueï¼å¤±è´¥åè¿åfalseã tryAcquireShared(int)//å ±äº«æ¹å¼ãå°è¯è·åèµæºãè´æ°è¡¨ç¤ºå¤±è´¥ï¼0表示æåï¼ä½æ²¡æå©ä½å¯ç¨èµæºï¼æ£æ°è¡¨ç¤ºæåï¼ä¸æå©ä½èµæºã tryReleaseShared(int)//å ±äº«æ¹å¼ãå°è¯éæ¾èµæºï¼æååè¿åtrueï¼å¤±è´¥åè¿åfalseã ``` é»è®¤æ åµä¸ï¼æ¯ä¸ªæ¹æ³é½æåº `UnsupportedOperationException`ã è¿äºæ¹æ³çå®ç°å¿ é¡»æ¯å é¨çº¿ç¨å®å ¨çï¼å¹¶ä¸é常åºè¯¥ç®çè䏿¯é»å¡ãAQSç±»ä¸çå ¶ä»æ¹æ³é½æ¯final ï¼æä»¥æ æ³è¢«å ¶ä»ç±»ä½¿ç¨ï¼åªæè¿å ä¸ªæ¹æ³å¯ä»¥è¢«å ¶ä»ç±»ä½¿ç¨ã 以ReentrantLock为ä¾ï¼stateåå§å为0ï¼è¡¨ç¤ºæªéå®ç¶æãA线ç¨lock()æ¶ï¼ä¼è°ç¨tryAcquire()ç¬å 该éå¹¶å°state+1ãæ¤åï¼å ¶ä»çº¿ç¨åtryAcquire()æ¶å°±ä¼å¤±è´¥ï¼ç´å°A线ç¨unlock()å°state=0ï¼å³éæ¾éï¼ä¸ºæ¢ï¼å ¶å®çº¿ç¨æææºä¼è·å该éãå½ç¶ï¼éæ¾éä¹åï¼A线ç¨èªå·±æ¯å¯ä»¥éå¤è·åæ¤éçï¼stateä¼ç´¯å ï¼ï¼è¿å°±æ¯å¯éå ¥çæ¦å¿µãä½è¦æ³¨æï¼è·åå¤å°æ¬¡å°±è¦éæ¾å¤ä¹æ¬¡ï¼è¿æ ·æè½ä¿è¯stateæ¯è½åå°é¶æçã å以CountDownLatch以ä¾ï¼ä»»å¡å为N个å线ç¨å»æ§è¡ï¼stateä¹åå§å为Nï¼æ³¨æNè¦ä¸çº¿ç¨ä¸ªæ°ä¸è´ï¼ãè¿N个åçº¿ç¨æ¯å¹¶è¡æ§è¡çï¼æ¯ä¸ªåçº¿ç¨æ§è¡å®åcountDown()䏿¬¡ï¼stateä¼CAS(Compare and Swap)å1ãçå°ææå线ç¨é½æ§è¡å®å(å³state=0)ï¼ä¼unpark()主è°ç¨çº¿ç¨ï¼ç¶å主è°ç¨çº¿ç¨å°±ä¼ä»await()彿°è¿åï¼ç»§ç»åä½å¨ä½ã ä¸è¬æ¥è¯´ï¼èªå®ä¹åæ¥å¨è¦ä¹æ¯ç¬å æ¹æ³ï¼è¦ä¹æ¯å ±äº«æ¹å¼ï¼ä»ä»¬ä¹åªéå®ç°`tryAcquire-tryRelease`ã`tryAcquireShared-tryReleaseShared`ä¸çä¸ç§å³å¯ãä½AQS乿¯æèªå®ä¹åæ¥å¨åæ¶å®ç°ç¬å åå ±äº«ä¸¤ç§æ¹å¼ï¼å¦`ReentrantReadWriteLock`ã æ¨èä¸¤ç¯ AQS åçåç¸å ³æºç åæçæç« ï¼ - http://www.cnblogs.com/waterystone/p/4920797.html - https://www.cnblogs.com/chengxiao/archive/2017/07/24/7141160.html ### 3 Semaphore(ä¿¡å·é)-å 许å¤ä¸ªçº¿ç¨åæ¶è®¿é® **synchronized å ReentrantLock 齿¯ä¸æ¬¡åªå 许ä¸ä¸ªçº¿ç¨è®¿é®æä¸ªèµæºï¼Semaphore(ä¿¡å·é)å¯ä»¥æå®å¤ä¸ªçº¿ç¨åæ¶è®¿é®æä¸ªèµæºã**示ä¾ä»£ç å¦ä¸ï¼ ```java /** * * @author Snailclimb * @date 2018å¹´9æ30æ¥ * @Description: éè¦ä¸æ¬¡æ§æ¿ä¸ä¸ªè®¸å¯çæ åµ */ public class SemaphoreExample1 { // 请æ±çæ°é private static final int threadCount = 550; public static void main(String[] args) throws InterruptedException { // å建ä¸ä¸ªå ·æåºå®çº¿ç¨æ°éççº¿ç¨æ± 对象ï¼å¦æè¿éçº¿ç¨æ± ççº¿ç¨æ°éç»å¤ªå°çè¯ä½ ä¼åç°æ§è¡ç徿 ¢ï¼ ExecutorService threadPool = Executors.newFixedThreadPool(300); // 䏿¬¡åªè½å 许æ§è¡ççº¿ç¨æ°éã final Semaphore semaphore = new Semaphore(20); for (int i = 0; i < threadCount; i++) { final int threadnum = i; threadPool.execute(() -> {// Lambda 表达å¼çè¿ç¨ try { semaphore.acquire();// è·åä¸ä¸ªè®¸å¯ï¼æä»¥å¯è¿è¡çº¿ç¨æ°é为20/1=20 test(threadnum); semaphore.release();// éæ¾ä¸ä¸ªè®¸å¯ } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }); } threadPool.shutdown(); System.out.println("finish"); } public static void test(int threadnum) throws InterruptedException { Thread.sleep(1000);// 模æè¯·æ±çèæ¶æä½ System.out.println("threadnum:" + threadnum); Thread.sleep(1000);// 模æè¯·æ±çèæ¶æä½ } } ``` æ§è¡ `acquire` æ¹æ³é»å¡ï¼ç´å°æä¸ä¸ªè®¸å¯è¯å¯ä»¥è·å¾ç¶åæ¿èµ°ä¸ä¸ªè®¸å¯è¯ï¼æ¯ä¸ª `release` æ¹æ³å¢å ä¸ä¸ªè®¸å¯è¯ï¼è¿å¯è½ä¼éæ¾ä¸ä¸ªé»å¡çacquireæ¹æ³ãç¶èï¼å ¶å®å¹¶æ²¡æå®é ç许å¯è¯è¿ä¸ªå¯¹è±¡ï¼Semaphoreåªæ¯ç»´æäºä¸ä¸ªå¯è·å¾è®¸å¯è¯çæ°éã Semaphoreç»å¸¸ç¨äºéå¶è·åæç§èµæºççº¿ç¨æ°éã å½ç¶ä¸æ¬¡ä¹å¯ä»¥ä¸æ¬¡æ¿ååéæ¾å¤ä¸ªè®¸å¯ï¼ä¸è¿ä¸è¬æ²¡æå¿ è¦è¿æ ·åï¼ ```java semaphore.acquire(5);// è·å5个许å¯ï¼æä»¥å¯è¿è¡çº¿ç¨æ°é为20/5=4 test(threadnum); semaphore.release(5);// è·å5个许å¯ï¼æä»¥å¯è¿è¡çº¿ç¨æ°é为20/5=4 ``` é¤äº `acquire`æ¹æ³ä¹å¤ï¼å¦ä¸ä¸ªæ¯è¾å¸¸ç¨çä¸ä¹å¯¹åºçæ¹æ³æ¯`tryAcquire`æ¹æ³ï¼è¯¥æ¹æ³å¦æè·åä¸å°è®¸å¯å°±ç«å³è¿åfalseã Semaphore æä¸¤ç§æ¨¡å¼ï¼å ¬å¹³æ¨¡å¼åéå ¬å¹³æ¨¡å¼ã - **å ¬å¹³æ¨¡å¼ï¼** è°ç¨acquireç顺åºå°±æ¯è·å许å¯è¯ç顺åºï¼éµå¾ªFIFOï¼ - **éå ¬å¹³æ¨¡å¼ï¼** æ¢å å¼çã **Semaphore 对åºç两个æé æ¹æ³å¦ä¸ï¼** ```java public Semaphore(int permits) { sync = new NonfairSync(permits); } public Semaphore(int permits, boolean fair) { sync = fair ? new FairSync(permits) : new NonfairSync(permits); } ``` **è¿ä¸¤ä¸ªæé æ¹æ³ï¼é½å¿ é¡»æä¾è®¸å¯çæ°éï¼ç¬¬äºä¸ªæé æ¹æ³å¯ä»¥æå®æ¯å ¬å¹³æ¨¡å¼è¿æ¯éå ¬å¹³æ¨¡å¼ï¼é»è®¤éå ¬å¹³æ¨¡å¼ã** ç±äºç¯å¹ é®é¢ï¼å¦æå¯¹ Semaphore æºç æå ´è¶£çæåå¯ä»¥çä¸é¢è¿ç¯æç« ï¼ - https://blog.csdn.net/qq_19431333/article/details/70212663 ### 4 CountDownLatch ï¼å计æ¶å¨ï¼ CountDownLatchæ¯ä¸ä¸ªåæ¥å·¥å ·ç±»ï¼å®å 许ä¸ä¸ªæå¤ä¸ªçº¿ç¨ä¸ç´çå¾ ï¼ç´å°å ¶ä»çº¿ç¨çæä½æ§è¡å®ååæ§è¡ãå¨Javaå¹¶åä¸ï¼countdownlatchçæ¦å¿µæ¯ä¸ä¸ªå¸¸è§çé¢è¯é¢ï¼æä»¥ä¸å®è¦ç¡®ä¿ä½ å¾å¥½ççè§£äºå®ã #### 4.1 CountDownLatch çä¸ç§å ¸åç¨æ³ â æä¸çº¿ç¨å¨å¼å§è¿è¡åçå¾ nä¸ªçº¿ç¨æ§è¡å®æ¯ãå° CountDownLatch ç计æ°å¨åå§å为n ï¼`new CountDownLatch(n) `ï¼æ¯å½ä¸ä¸ªä»»å¡çº¿ç¨æ§è¡å®æ¯ï¼å°±å°è®¡æ°å¨å1 `countdownlatch.countDown()`ï¼å½è®¡æ°å¨çå¼å为0æ¶ï¼å¨`CountDownLatchä¸ await()` ç线ç¨å°±ä¼è¢«å¤éãä¸ä¸ªå ¸ååºç¨åºæ¯å°±æ¯å¯å¨ä¸ä¸ªæå¡æ¶ï¼ä¸»çº¿ç¨éè¦çå¾ å¤ä¸ªç»ä»¶å è½½å®æ¯ï¼ä¹ååç»§ç»æ§è¡ã â¡å®ç°å¤ä¸ªçº¿ç¨å¼å§æ§è¡ä»»å¡çæå¤§å¹¶è¡æ§ãæ³¨ææ¯å¹¶è¡æ§ï¼ä¸æ¯å¹¶åï¼å¼ºè°çæ¯å¤ä¸ªçº¿ç¨å¨æä¸æ¶å»åæ¶å¼å§æ§è¡ã类似äºèµè·ï¼å°å¤ä¸ªçº¿ç¨æ¾å°èµ·ç¹ï¼çå¾ å令æªåï¼ç¶ååæ¶å¼è·ãåæ³æ¯åå§åä¸ä¸ªå ±äº«ç `CountDownLatch` 对象ï¼å°å ¶è®¡æ°å¨åå§å为 1 ï¼`new CountDownLatch(1) `ï¼å¤ä¸ªçº¿ç¨å¨å¼å§æ§è¡ä»»å¡åé¦å `coundownlatch.await()`ï¼å½ä¸»çº¿ç¨è°ç¨ countDown() æ¶ï¼è®¡æ°å¨å为0ï¼å¤ä¸ªçº¿ç¨åæ¶è¢«å¤éã â¢æ»éæ£æµï¼ä¸ä¸ªé常æ¹ä¾¿ç使ç¨åºæ¯æ¯ï¼ä½ å¯ä»¥ä½¿ç¨n个线ç¨è®¿é®å ±äº«èµæºï¼å¨æ¯æ¬¡æµè¯é¶æ®µççº¿ç¨æ°ç®æ¯ä¸åçï¼å¹¶å°è¯äº§çæ»éã #### 4.2 CountDownLatch ç使ç¨ç¤ºä¾ ```java /** * * @author SnailClimb * @date 2018å¹´10æ1æ¥ * @Description: CountDownLatch ä½¿ç¨æ¹æ³ç¤ºä¾ */ public class CountDownLatchExample1 { // 请æ±çæ°é private static final int threadCount = 550; public static void main(String[] args) throws InterruptedException { // å建ä¸ä¸ªå ·æåºå®çº¿ç¨æ°éççº¿ç¨æ± 对象ï¼å¦æè¿éçº¿ç¨æ± ççº¿ç¨æ°éç»å¤ªå°çè¯ä½ ä¼åç°æ§è¡ç徿 ¢ï¼ ExecutorService threadPool = Executors.newFixedThreadPool(300); final CountDownLatch countDownLatch = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { final int threadnum = i; threadPool.execute(() -> {// Lambda 表达å¼çè¿ç¨ try { test(threadnum); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { countDownLatch.countDown();// 表示ä¸ä¸ªè¯·æ±å·²ç»è¢«å®æ } }); } countDownLatch.await(); threadPool.shutdown(); System.out.println("finish"); } public static void test(int threadnum) throws InterruptedException { Thread.sleep(1000);// 模æè¯·æ±çèæ¶æä½ System.out.println("threadnum:" + threadnum); Thread.sleep(1000);// 模æè¯·æ±çèæ¶æä½ } } ``` ä¸é¢ç代ç ä¸ï¼æä»¬å®ä¹äºè¯·æ±çæ°é为550ï¼å½è¿550个请æ±è¢«å¤ç宿ä¹åï¼æä¼æ§è¡`System.out.println("finish");`ã ä¸CountDownLatchçç¬¬ä¸æ¬¡äº¤äºæ¯ä¸»çº¿ç¨çå¾ å ¶ä»çº¿ç¨ã主线ç¨å¿ é¡»å¨å¯å¨å ¶ä»çº¿ç¨åç«å³è°ç¨CountDownLatch.await()æ¹æ³ãè¿æ ·ä¸»çº¿ç¨çæä½å°±ä¼å¨è¿ä¸ªæ¹æ³ä¸é»å¡ï¼ç´å°å ¶ä»çº¿ç¨å®æåèªçä»»å¡ã å ¶ä»N个线ç¨å¿ é¡»å¼ç¨éé对象ï¼å 为ä»ä»¬éè¦éç¥CountDownLatch对象ï¼ä»ä»¬å·²ç»å®æäºåèªçä»»å¡ãè¿ç§éç¥æºå¶æ¯éè¿ CountDownLatch.countDown()æ¹æ³æ¥å®æçï¼æ¯è°ç¨ä¸æ¬¡è¿ä¸ªæ¹æ³ï¼å¨æé 彿°ä¸åå§åçcountå¼å°±å1ãæä»¥å½N个线ç¨é½è° ç¨äºè¿ä¸ªæ¹æ³ï¼countçå¼çäº0ï¼ç¶å主线ç¨å°±è½éè¿await()æ¹æ³ï¼æ¢å¤æ§è¡èªå·±çä»»å¡ã #### 4.3 CountDownLatch çä¸è¶³ CountDownLatchæ¯ä¸æ¬¡æ§çï¼è®¡æ°å¨çå¼åªè½å¨æé æ¹æ³ä¸åå§å䏿¬¡ï¼ä¹å没æä»»ä½æºå¶åæ¬¡å¯¹å ¶è®¾ç½®å¼ï¼å½CountDownLatch使ç¨å®æ¯åï¼å®ä¸è½å次被使ç¨ã #### 4.4 CountDownLatchç¸å¸¸è§é¢è¯é¢ï¼ è§£éä¸ä¸CountDownLatchæ¦å¿µï¼ CountDownLatch åCyclicBarrierçä¸åä¹å¤ï¼ ç»åºä¸äºCountDownLatch使ç¨çä¾åï¼ CountDownLatch ç±»ä¸ä¸»è¦çæ¹æ³ï¼ ### 5 CyclicBarrier(å¾ªç¯æ æ ) CyclicBarrier å CountDownLatch é常类似ï¼å®ä¹å¯ä»¥å®ç°çº¿ç¨é´çææ¯çå¾ ï¼ä½æ¯å®çåè½æ¯ CountDownLatch æ´å 夿å强大ã主è¦åºç¨åºæ¯å CountDownLatch 类似ã CyclicBarrier çåé¢æææ¯å¯å¾ªç¯ä½¿ç¨ï¼Cyclicï¼çå±éï¼Barrierï¼ãå®è¦åçäºæ æ¯ï¼è®©ä¸ç»çº¿ç¨å°è¾¾ä¸ä¸ªå±éï¼ä¹å¯ä»¥å«åæ¥ç¹ï¼æ¶è¢«é»å¡ï¼ç´å°æåä¸ä¸ªçº¿ç¨å°è¾¾å±éæ¶ï¼å±éæä¼å¼é¨ï¼ææè¢«å±éæ¦æªççº¿ç¨æä¼ç»§ç»å¹²æ´»ãCyclicBarrieré»è®¤çæé æ¹æ³æ¯ `CyclicBarrier(int parties)`ï¼å ¶åæ°è¡¨ç¤ºå±éæ¦æªççº¿ç¨æ°éï¼æ¯ä¸ªçº¿ç¨è°ç¨`await`æ¹æ³åè¯ CyclicBarrier æå·²ç»å°è¾¾äºå±éï¼ç¶åå½å线ç¨è¢«é»å¡ã #### 5.1 CyclicBarrier çåºç¨åºæ¯ CyclicBarrier å¯ä»¥ç¨äºå¤çº¿ç¨è®¡ç®æ°æ®ï¼æåå并计ç®ç»æçåºç¨åºæ¯ãæ¯å¦æä»¬ç¨ä¸ä¸ªExcelä¿åäºç¨æ·ææé¶è¡æµæ°´ï¼æ¯ä¸ªSheetä¿åä¸ä¸ªå¸æ·è¿ä¸å¹´çæ¯ç¬é¶è¡æµæ°´ï¼ç°å¨éè¦ç»è®¡ç¨æ·çæ¥åé¶è¡æµæ°´ï¼å ç¨å¤çº¿ç¨å¤çæ¯ä¸ªsheetéçé¶è¡æµæ°´ï¼é½æ§è¡å®ä¹åï¼å¾å°æ¯ä¸ªsheetçæ¥åé¶è¡æµæ°´ï¼æåï¼åç¨barrierActionç¨è¿äºçº¿ç¨ç计ç®ç»æï¼è®¡ç®åºæ´ä¸ªExcelçæ¥åé¶è¡æµæ°´ã #### 5.2 CyclicBarrier ç使ç¨ç¤ºä¾ 示ä¾1ï¼ ```java /** * * @author Snailclimb * @date 2018å¹´10æ1æ¥ * @Description: æµè¯ CyclicBarrier ç±»ä¸å¸¦åæ°ç await() æ¹æ³ */ public class CyclicBarrierExample2 { // 请æ±çæ°é private static final int threadCount = 550; // éè¦åæ¥ççº¿ç¨æ°é private static final CyclicBarrier cyclicBarrier = new CyclicBarrier(5); public static void main(String[] args) throws InterruptedException { // åå»ºçº¿ç¨æ± ExecutorService threadPool = Executors.newFixedThreadPool(10); for (int i = 0; i < threadCount; i++) { final int threadNum = i; Thread.sleep(1000); threadPool.execute(() -> { try { test(threadNum); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (BrokenBarrierException e) { // TODO Auto-generated catch block e.printStackTrace(); } }); } threadPool.shutdown(); } public static void test(int threadnum) throws InterruptedException, BrokenBarrierException { System.out.println("threadnum:" + threadnum + "is ready"); try { /**çå¾ 60ç§ï¼ä¿è¯å线ç¨å®å ¨æ§è¡ç»æ*/ cyclicBarrier.await(60, TimeUnit.SECONDS); } catch (Exception e) { System.out.println("-----CyclicBarrierException------"); } System.out.println("threadnum:" + threadnum + "is finish"); } } ``` è¿è¡ç»æï¼å¦ä¸ï¼ ``` threadnum:0is ready threadnum:1is ready threadnum:2is ready threadnum:3is ready threadnum:4is ready threadnum:4is finish threadnum:0is finish threadnum:1is finish threadnum:2is finish threadnum:3is finish threadnum:5is ready threadnum:6is ready threadnum:7is ready threadnum:8is ready threadnum:9is ready threadnum:9is finish threadnum:5is finish threadnum:8is finish threadnum:7is finish threadnum:6is finish ...... ``` å¯ä»¥çå°å½çº¿ç¨æ°éä¹å°±æ¯è¯·æ±æ°éè¾¾å°æä»¬å®ä¹ç 5 ä¸ªçæ¶åï¼ `await`æ¹æ³ä¹åçæ¹æ³æè¢«æ§è¡ã å¦å¤ï¼CyclicBarrierè¿æä¾ä¸ä¸ªæ´é«çº§çæé 彿°`CyclicBarrier(int parties, Runnable barrierAction)`ï¼ç¨äºå¨çº¿ç¨å°è¾¾å±éæ¶ï¼ä¼å æ§è¡`barrierAction`ï¼æ¹ä¾¿å¤çæ´å¤æçä¸å¡åºæ¯ã示ä¾ä»£ç å¦ä¸ï¼ ```java /** * * @author SnailClimb * @date 2018å¹´10æ1æ¥ * @Description: æ°å»º CyclicBarrier çæ¶åæå®ä¸ä¸ª Runnable */ public class CyclicBarrierExample3 { // 请æ±çæ°é private static final int threadCount = 550; // éè¦åæ¥ççº¿ç¨æ°é private static final CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> { System.out.println("------å½çº¿ç¨æ°è¾¾å°ä¹åï¼ä¼å æ§è¡------"); }); public static void main(String[] args) throws InterruptedException { // åå»ºçº¿ç¨æ± ExecutorService threadPool = Executors.newFixedThreadPool(10); for (int i = 0; i < threadCount; i++) { final int threadNum = i; Thread.sleep(1000); threadPool.execute(() -> { try { test(threadNum); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (BrokenBarrierException e) { // TODO Auto-generated catch block e.printStackTrace(); } }); } threadPool.shutdown(); } public static void test(int threadnum) throws InterruptedException, BrokenBarrierException { System.out.println("threadnum:" + threadnum + "is ready"); cyclicBarrier.await(); System.out.println("threadnum:" + threadnum + "is finish"); } } ``` è¿è¡ç»æï¼å¦ä¸ï¼ ``` threadnum:0is ready threadnum:1is ready threadnum:2is ready threadnum:3is ready threadnum:4is ready ------å½çº¿ç¨æ°è¾¾å°ä¹åï¼ä¼å æ§è¡------ threadnum:4is finish threadnum:0is finish threadnum:2is finish threadnum:1is finish threadnum:3is finish threadnum:5is ready threadnum:6is ready threadnum:7is ready threadnum:8is ready threadnum:9is ready ------å½çº¿ç¨æ°è¾¾å°ä¹åï¼ä¼å æ§è¡------ threadnum:9is finish threadnum:5is finish threadnum:6is finish threadnum:8is finish threadnum:7is finish ...... ``` #### 5.3 CyclicBarrieråCountDownLatchçåºå« CountDownLatchæ¯è®¡æ°å¨ï¼åªè½ä½¿ç¨ä¸æ¬¡ï¼èCyclicBarrierç计æ°å¨æä¾resetåè½ï¼å¯ä»¥å¤æ¬¡ä½¿ç¨ã使¯æä¸é£ä¹è®¤ä¸ºå®ä»¬ä¹é´çåºå«ä» ä» å°±æ¯è¿ä¹ç®åçä¸ç¹ãæä»¬æ¥ä»jdkä½è 设计çç®çæ¥çï¼javadocæ¯è¿ä¹æè¿°å®ä»¬çï¼ > CountDownLatch: A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.(CountDownLatch: ä¸ä¸ªæè å¤ä¸ªçº¿ç¨ï¼çå¾ å ¶ä»å¤ä¸ªçº¿ç¨å®ææä»¶äºæ ä¹åæè½æ§è¡ï¼) > CyclicBarrier : A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.(CyclicBarrier : å¤ä¸ªçº¿ç¨äºç¸çå¾ ï¼ç´å°å°è¾¾åä¸ä¸ªåæ¥ç¹ï¼åç»§ç»ä¸èµ·æ§è¡ã) 对äºCountDownLatchæ¥è¯´ï¼éç¹æ¯âä¸ä¸ªçº¿ç¨ï¼å¤ä¸ªçº¿ç¨ï¼çå¾ âï¼èå ¶ä»çN个线ç¨å¨å®æâæä»¶äºæ âä¹åï¼å¯ä»¥ç»æ¢ï¼ä¹å¯ä»¥çå¾ ãè对äºCyclicBarrierï¼éç¹æ¯å¤ä¸ªçº¿ç¨ï¼å¨ä»»æä¸ä¸ªçº¿ç¨æ²¡æå®æï¼ææç线ç¨é½å¿ é¡»çå¾ ã CountDownLatchæ¯è®¡æ°å¨ï¼çº¿ç¨å®æä¸ä¸ªè®°å½ä¸ä¸ªï¼åªä¸è¿è®¡æ°ä¸æ¯éå¢èæ¯éåï¼èCyclicBarrieræ´åæ¯ä¸ä¸ªéé¨ï¼éè¦ææçº¿ç¨é½å°è¾¾ï¼éé¨æè½æå¼ï¼ç¶åç»§ç»æ§è¡ã  CyclicBarrieråCountDownLatchçåºå«è¿é¨åå 容åèäºå¦ä¸ä¸¤ç¯æç« ï¼ - https://blog.csdn.net/u010185262/article/details/54692886 - https://blog.csdn.net/tolcf/article/details/50925145?utm_source=blogxgwz0 ### 6 ReentrantLock å ReentrantReadWriteLock ReentrantLock å synchronized çåºå«å¨ä¸é¢å·²ç»è®²è¿äºè¿éå°±ä¸å¤å讲解ãå¦å¤ï¼éè¦æ³¨æçæ¯ï¼è¯»åé ReentrantReadWriteLock å¯ä»¥ä¿è¯å¤ä¸ªçº¿ç¨å¯ä»¥åæ¶è¯»ï¼æä»¥å¨è¯»æä½è¿å¤§äºåæä½çæ¶åï¼è¯»åéå°±é常æç¨äºã ç±äºç¯å¹ é®é¢ï¼å ³äº ReentrantLock å ReentrantReadWriteLock 详ç»å 容å¯ä»¥æ¥çæçè¿ç¯ååæç« ã - [ReentrantLock å ReentrantReadWriteLock](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247483745&idx=2&sn=6778ee954a19816310df54ef9a3c2f8a&chksm=fd985700caefde16b9970f5e093b0c140d3121fb3a8458b11871e5e9723c5fd1b5a961fd2228&token=1829606453&lang=zh_CN#rd)