ç¹å»å ³æ³¨[å ¬ä¼å·](#å ¬ä¼å· "å ¬ä¼å·")åæ¶è·åç¬ä¸»ææ°æ´æ°æç« ï¼å¹¶å¯å è´¹é¢åæ¬ææ¡£é å¥çãJava é¢è¯çªå»ã以å Java å·¥ç¨å¸å¿ å¤å¦ä¹ èµæºã - [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`æºç åæ](#53-cyclicbarrieræºç åæ) - [5.4 CyclicBarrier å CountDownLatch çåºå«](#54-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(jdk1.7) çççæ¯åºäº 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 å®ä¹ä¸¤ç§èµæºå ±äº«æ¹å¼** **1)Exclusive**ï¼ç¬å ï¼ åªæä¸ä¸ªçº¿ç¨è½æ§è¡ï¼å¦ ReentrantLockãåå¯åä¸ºå ¬å¹³éåéå ¬å¹³é,ReentrantLock åæ¶æ¯æä¸¤ç§é,ä¸é¢ä»¥ ReentrantLock 对è¿ä¸¤ç§éçå®ä¹åä»ç»ï¼ - å ¬å¹³éï¼æç §çº¿ç¨å¨éåä¸çæé顺åºï¼å å°è å æ¿å°é - éå ¬å¹³éï¼å½çº¿ç¨è¦è·åéæ¶ï¼å éè¿ä¸¤æ¬¡ CAS æä½å»æ¢éï¼å¦ææ²¡æ¢å°ï¼å½å线ç¨åå å ¥å°éåä¸çå¾ å¤éã > 说æï¼ä¸é¢è¿é¨åå ³äº `ReentrantLock` æºä»£ç å 容èéèªï¼https://www.javadoop.com/post/AbstractQueuedSynchronizer-2 ï¼è¿æ¯ä¸ç¯å¾ä¸éæç« ï¼æ¨èé 读ã **ä¸é¢æ¥ç ReentrantLock ä¸ç¸å ³çæºä»£ç ï¼** ReentrantLock é»è®¤éç¨éå ¬å¹³éï¼å 为èèè·å¾æ´å¥½çæ§è½ï¼éè¿ boolean æ¥å³å®æ¯å¦ç¨å ¬å¹³éï¼ä¼ å ¥ true ç¨å ¬å¹³éï¼ã ```java /** Synchronizer providing all implementation mechanics */ private final Sync sync; public ReentrantLock() { // é»è®¤éå ¬å¹³é sync = new NonfairSync(); } public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); } ``` ReentrantLock ä¸å ¬å¹³éç `lock` æ¹æ³ ```java static final class FairSync extends Sync { final void lock() { acquire(1); } // AbstractQueuedSynchronizer.acquire(int arg) public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); } protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { // 1. åéå ¬å¹³éç¸æ¯ï¼è¿éå¤äºä¸ä¸ªå¤æï¼æ¯å¦æçº¿ç¨å¨çå¾ if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; } } ``` éå ¬å¹³éç lock æ¹æ³ï¼ ```java static final class NonfairSync extends Sync { final void lock() { // 2. åå ¬å¹³éç¸æ¯ï¼è¿éä¼ç´æ¥å è¿è¡ä¸æ¬¡CASï¼æåå°±è¿åäº if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } // AbstractQueuedSynchronizer.acquire(int arg) public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); } protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } } /** * Performs non-fair tryLock. tryAcquire is implemented in * subclasses, but both need nonfair try for trylock method. */ final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); 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; } return false; } ``` æ»ç»ï¼å ¬å¹³éåéå ¬å¹³éåªæä¸¤å¤ä¸åï¼ 1. éå ¬å¹³éå¨è°ç¨ lock åï¼é¦å å°±ä¼è°ç¨ CAS è¿è¡ä¸æ¬¡æ¢éï¼å¦æè¿ä¸ªæ¶åæ°å·§é没æè¢«å ç¨ï¼é£ä¹ç´æ¥å°±è·åå°éè¿åäºã 2. éå ¬å¹³éå¨ CAS 失败åï¼åå ¬å¹³é䏿 ·é½ä¼è¿å ¥å° tryAcquire æ¹æ³ï¼å¨ tryAcquire æ¹æ³ä¸ï¼å¦æåç°éè¿ä¸ªæ¶åè¢«éæ¾äºï¼state == 0ï¼ï¼éå ¬å¹³éä¼ç´æ¥ CAS æ¢éï¼ä½æ¯å ¬å¹³éä¼å¤æçå¾ éåæ¯å¦æçº¿ç¨å¤äºçå¾ ç¶æï¼å¦ææåä¸å»æ¢éï¼ä¹ä¹æå°åé¢ã å ¬å¹³éåéå ¬å¹³éå°±è¿ä¸¤ç¹åºå«ï¼å¦æè¿ä¸¤æ¬¡ CAS é½ä¸æåï¼é£ä¹åé¢éå ¬å¹³éåå ¬å¹³éæ¯ä¸æ ·çï¼é½è¦è¿å ¥å°é»å¡éåçå¾ å¤éã ç¸å¯¹æ¥è¯´ï¼éå ¬å¹³é伿æ´å¥½çæ§è½ï¼å 为å®çåå鿝è¾å¤§ãå½ç¶ï¼éå ¬å¹³é让è·åéçæ¶é´å徿´å ä¸ç¡®å®ï¼å¯è½ä¼å¯¼è´å¨é»å¡éåä¸ç线ç¨é¿æå¤äºé¥¥é¥¿ç¶æã **2)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); } ``` **è¿ä¸¤ä¸ªæé æ¹æ³ï¼é½å¿ é¡»æä¾è®¸å¯çæ°éï¼ç¬¬äºä¸ªæé æ¹æ³å¯ä»¥æå®æ¯å ¬å¹³æ¨¡å¼è¿æ¯éå ¬å¹³æ¨¡å¼ï¼é»è®¤éå ¬å¹³æ¨¡å¼ã** [issue645è¡¥å å 容](https://github.com/Snailclimb/JavaGuide/issues/645) ï¼Semaphoreä¸CountDownLatch䏿 ·ï¼ä¹æ¯å ±äº«éçä¸ç§å®ç°ãå®é»è®¤æé AQSçstate为permitsã彿§è¡ä»»å¡ççº¿ç¨æ°éè¶ åºpermits,é£ä¹å¤ä½ç线ç¨å°ä¼è¢«æ¾å ¥é»å¡éåPark,å¹¶èªæå¤æstateæ¯å¦å¤§äº0ãåªæå½state大äº0çæ¶åï¼é»å¡ççº¿ç¨æè½ç»§ç»æ§è¡,æ¤æ¶å åæ§è¡ä»»å¡ç线ç¨ç»§ç»æ§è¡releaseæ¹æ³ï¼releaseæ¹æ³ä½¿å¾stateçåéä¼å 1ï¼é£ä¹èªæç线ç¨ä¾¿ä¼å¤ææåã 妿¤ï¼æ¯æ¬¡åªææå¤ä¸è¶ è¿permitsæ°éç线ç¨è½èªææåï¼ä¾¿éå¶äºæ§è¡ä»»å¡çº¿ç¨çæ°éã ç±äºç¯å¹ é®é¢ï¼å¦æå¯¹ Semaphore æºç æå ´è¶£çæåå¯ä»¥çä¸è¿ç¯æç« ï¼https://juejin.im/post/5ae755366fb9a07ab508adc6 ### 4 CountDownLatch ï¼å计æ¶å¨ï¼ CountDownLatchå 许 count 个线ç¨é»å¡å¨ä¸ä¸ªå°æ¹ï¼ç´è³ææçº¿ç¨çä»»å¡é½æ§è¡å®æ¯ãå¨ Java å¹¶åä¸ï¼countdownlatch çæ¦å¿µæ¯ä¸ä¸ªå¸¸è§çé¢è¯é¢ï¼æä»¥ä¸å®è¦ç¡®ä¿ä½ å¾å¥½ççè§£äºå®ã CountDownLatchæ¯å ±äº«éçä¸ç§å®ç°,å®é»è®¤æé AQS ç state å¼ä¸º countãå½çº¿ç¨ä½¿ç¨countDownæ¹æ³æ¶,å ¶å®ä½¿ç¨äº`tryReleaseShared`æ¹æ³ä»¥CASçæä½æ¥åå°state,ç´è³state为0就代表ææç线ç¨é½è°ç¨äºcountDownæ¹æ³ãå½è°ç¨awaitæ¹æ³çæ¶åï¼å¦æstateä¸ä¸º0ï¼å°±ä»£è¡¨ä»ç¶æçº¿ç¨æ²¡æè°ç¨countDownæ¹æ³ï¼é£ä¹å°±æå·²ç»è°ç¨è¿countDownç线ç¨é½æ¾å ¥é»å¡éåPark,å¹¶èªæCAS夿state == 0ï¼ç´è³æåä¸ä¸ªçº¿ç¨è°ç¨äºcountDownï¼ä½¿å¾state == 0ï¼äºæ¯é»å¡ç线ç¨ä¾¿å¤ææåï¼å ¨é¨å¾ä¸æ§è¡ã #### 4.1 CountDownLatch ç两ç§å ¸åç¨æ³ 1. æä¸çº¿ç¨å¨å¼å§è¿è¡åçå¾ n ä¸ªçº¿ç¨æ§è¡å®æ¯ãå° CountDownLatch ç计æ°å¨åå§å为 n ï¼`new CountDownLatch(n)`ï¼æ¯å½ä¸ä¸ªä»»å¡çº¿ç¨æ§è¡å®æ¯ï¼å°±å°è®¡æ°å¨å 1 `countdownlatch.countDown()`ï¼å½è®¡æ°å¨çå¼å为 0 æ¶ï¼å¨`CountDownLatchä¸ await()` ç线ç¨å°±ä¼è¢«å¤éãä¸ä¸ªå ¸ååºç¨åºæ¯å°±æ¯å¯å¨ä¸ä¸ªæå¡æ¶ï¼ä¸»çº¿ç¨éè¦çå¾ å¤ä¸ªç»ä»¶å è½½å®æ¯ï¼ä¹ååç»§ç»æ§è¡ã 2. å®ç°å¤ä¸ªçº¿ç¨å¼å§æ§è¡ä»»å¡çæå¤§å¹¶è¡æ§ãæ³¨ææ¯å¹¶è¡æ§ï¼ä¸æ¯å¹¶åï¼å¼ºè°çæ¯å¤ä¸ªçº¿ç¨å¨æä¸æ¶å»åæ¶å¼å§æ§è¡ã类似äºèµè·ï¼å°å¤ä¸ªçº¿ç¨æ¾å°èµ·ç¹ï¼çå¾ å令æªåï¼ç¶ååæ¶å¼è·ãåæ³æ¯åå§åä¸ä¸ªå ±äº«ç `CountDownLatch` 对象ï¼å°å ¶è®¡æ°å¨åå§å为 1 ï¼`new CountDownLatch(1)`ï¼å¤ä¸ªçº¿ç¨å¨å¼å§æ§è¡ä»»å¡åé¦å `coundownlatch.await()`ï¼å½ä¸»çº¿ç¨è°ç¨ countDown() æ¶ï¼è®¡æ°å¨å为 0ï¼å¤ä¸ªçº¿ç¨åæ¶è¢«å¤éã #### 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()`æ¹æ³ï¼æ¢å¤æ§è¡èªå·±çä»»å¡ã åæä¸å´ï¼`CountDownLatch` ç `await()` æ¹æ³ä½¿ç¨ä¸å½å¾å®¹æäº§çæ»éï¼æ¯å¦æä»¬ä¸é¢ä»£ç ä¸ç for å¾ªç¯æ¹ä¸ºï¼ ```java for (int i = 0; i < threadCount-1; i++) { ....... } ``` è¿æ ·å°±å¯¼è´ `count` ç弿²¡åæ³çäº 0ï¼ç¶åå°±ä¼å¯¼è´ä¸ç´çå¾ ã 妿坹CountDownLatchæºç æå ´è¶£çæåï¼å¯ä»¥æ¥çï¼ [ãJUCãJDK1.8æºç åæä¹CountDownLatchï¼äºï¼](https://www.cnblogs.com/leesf456/p/5406191.html) #### 4.3 CountDownLatch çä¸è¶³ CountDownLatch æ¯ä¸æ¬¡æ§çï¼è®¡æ°å¨çå¼åªè½å¨æé æ¹æ³ä¸åå§å䏿¬¡ï¼ä¹å没æä»»ä½æºå¶åæ¬¡å¯¹å ¶è®¾ç½®å¼ï¼å½ CountDownLatch 使ç¨å®æ¯åï¼å®ä¸è½å次被使ç¨ã #### 4.4 CountDownLatch ç¸å¸¸è§é¢è¯é¢ è§£éä¸ä¸ CountDownLatch æ¦å¿µï¼ CountDownLatch å CyclicBarrier çä¸åä¹å¤ï¼ ç»åºä¸äº CountDownLatch 使ç¨çä¾åï¼ CountDownLatch ç±»ä¸ä¸»è¦çæ¹æ³ï¼ ### 5 CyclicBarrier(å¾ªç¯æ æ ) CyclicBarrier å CountDownLatch é常类似ï¼å®ä¹å¯ä»¥å®ç°çº¿ç¨é´çææ¯çå¾ ï¼ä½æ¯å®çåè½æ¯ CountDownLatch æ´å 夿å强大ã主è¦åºç¨åºæ¯å CountDownLatch 类似ã > CountDownLatchçå®ç°æ¯åºäºAQSçï¼èCycliBarrieræ¯åºäº ReentrantLock(ReentrantLockä¹å±äºAQS忥å¨)å Condition ç. CyclicBarrier çåé¢æææ¯å¯å¾ªç¯ä½¿ç¨ï¼Cyclicï¼çå±éï¼Barrierï¼ãå®è¦åçäºæ æ¯ï¼è®©ä¸ç»çº¿ç¨å°è¾¾ä¸ä¸ªå±éï¼ä¹å¯ä»¥å«åæ¥ç¹ï¼æ¶è¢«é»å¡ï¼ç´å°æåä¸ä¸ªçº¿ç¨å°è¾¾å±éæ¶ï¼å±éæä¼å¼é¨ï¼ææè¢«å±éæ¦æªççº¿ç¨æä¼ç»§ç»å¹²æ´»ãCyclicBarrier é»è®¤çæé æ¹æ³æ¯ `CyclicBarrier(int parties)`ï¼å ¶åæ°è¡¨ç¤ºå±éæ¦æªççº¿ç¨æ°éï¼æ¯ä¸ªçº¿ç¨è°ç¨`await`æ¹æ³åè¯ CyclicBarrier æå·²ç»å°è¾¾äºå±éï¼ç¶åå½å线ç¨è¢«é»å¡ã 忥çä¸ä¸å®çæé 彿°ï¼ ```java public CyclicBarrier(int parties) { this(parties, null); } public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction; } ``` å ¶ä¸ï¼parties å°±ä»£è¡¨äºææ¦æªç线ç¨çæ°éï¼å½æ¦æªççº¿ç¨æ°éè¾¾å°è¿ä¸ªå¼çæ¶åå°±æå¼æ æ ï¼è®©ææçº¿ç¨éè¿ã #### 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`æºç åæ å½è°ç¨ `CyclicBarrier` 对象è°ç¨ `await()` æ¹æ³æ¶ï¼å®é ä¸è°ç¨çæ¯`dowait(false, 0L)`æ¹æ³ã `await()` æ¹æ³å°±åæ ç«èµ·ä¸ä¸ªæ æ çè¡ä¸ºä¸æ ·ï¼å°çº¿ç¨æ¡ä½äºï¼å½æ¦ä½ççº¿ç¨æ°éè¾¾å° parties ç弿¶ï¼æ æ æä¼æå¼ï¼çº¿ç¨æå¾ä»¥éè¿æ§è¡ã ```java public int await() throws InterruptedException, BrokenBarrierException { try { return dowait(false, 0L); } catch (TimeoutException toe) { throw new Error(toe); // cannot happen } } ``` `dowait(false, 0L)`ï¼ ```java // å½çº¿ç¨æ°éæè è¯·æ±æ°éè¾¾å° count æ¶ await ä¹åçæ¹æ³æä¼è¢«æ§è¡ãä¸é¢ç示ä¾ä¸ count çå¼å°±ä¸º 5ã private int count; /** * Main barrier code, covering the various policies. */ private int dowait(boolean timed, long nanos) throws InterruptedException, BrokenBarrierException, TimeoutException { final ReentrantLock lock = this.lock; // éä½ lock.lock(); try { final Generation g = generation; if (g.broken) throw new BrokenBarrierException(); // å¦æçº¿ç¨ä¸æäºï¼æåºå¼å¸¸ if (Thread.interrupted()) { breakBarrier(); throw new InterruptedException(); } // coutå1 int index = --count; // å½ count æ°éå为 0 ä¹å说ææåä¸ä¸ªçº¿ç¨å·²ç»å°è¾¾æ æ äºï¼ä¹å°±æ¯è¾¾å°äºå¯ä»¥æ§è¡await æ¹æ³ä¹åçæ¡ä»¶ if (index == 0) { // tripped boolean ranAction = false; try { final Runnable command = barrierCommand; if (command != null) command.run(); ranAction = true; // å° count é置为 parties 屿§çåå§åå¼ // å¤éä¹åçå¾ ççº¿ç¨ // ä¸ä¸æ³¢æ§è¡å¼å§ nextGeneration(); return 0; } finally { if (!ranAction) breakBarrier(); } } // loop until tripped, broken, interrupted, or timed out for (;;) { try { if (!timed) trip.await(); else if (nanos > 0L) nanos = trip.awaitNanos(nanos); } catch (InterruptedException ie) { if (g == generation && ! g.broken) { breakBarrier(); throw ie; } else { // We're about to finish waiting even if we had not // been interrupted, so this interrupt is deemed to // "belong" to subsequent execution. Thread.currentThread().interrupt(); } } if (g.broken) throw new BrokenBarrierException(); if (g != generation) return index; if (timed && nanos <= 0L) { breakBarrier(); throw new TimeoutException(); } } } finally { lock.unlock(); } } ``` æ»ç»ï¼`CyclicBarrier` å é¨éè¿ä¸ä¸ª count åéä½ä¸ºè®¡æ°å¨ï¼cout çåå§å¼ä¸º parties 屿§çåå§åå¼ï¼æ¯å½ä¸ä¸ªçº¿ç¨å°äºæ æ è¿éäºï¼é£ä¹å°±å°è®¡æ°å¨åä¸ã妿 count å¼ä¸º 0 äºï¼è¡¨ç¤ºè¿æ¯è¿ä¸ä»£æåä¸ä¸ªçº¿ç¨å°è¾¾æ æ ï¼å°±å°è¯æ§è¡æä»¬æé æ¹æ³ä¸è¾å ¥çä»»å¡ã #### 5.4 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 æ´åæ¯ä¸ä¸ªéé¨ï¼éè¦ææçº¿ç¨é½å°è¾¾ï¼éé¨æè½æå¼ï¼ç¶åç»§ç»æ§è¡ã ### 6 ReentrantLock å ReentrantReadWriteLock ReentrantLock å synchronized çåºå«å¨ä¸é¢å·²ç»è®²è¿äºè¿éå°±ä¸å¤å讲解ãå¦å¤ï¼éè¦æ³¨æçæ¯ï¼è¯»åé ReentrantReadWriteLock å¯ä»¥ä¿è¯å¤ä¸ªçº¿ç¨å¯ä»¥åæ¶è¯»ï¼æä»¥å¨è¯»æä½è¿å¤§äºåæä½çæ¶åï¼è¯»åéå°±é常æç¨äºã ### åè - https://juejin.im/post/5ae755256fb9a07ac3634067 - https://blog.csdn.net/u010185262/article/details/54692886 - https://blog.csdn.net/tolcf/article/details/50925145?utm_source=blogxgwz0 ### å ¬ä¼å· 妿大家æ³è¦å®æ¶å ³æ³¨ææ´æ°çæç« 以åå享ç干货çè¯ï¼å¯ä»¥å ³æ³¨æçå ¬ä¼å·ã **ãJava é¢è¯çªå»ã:** ç±æ¬ææ¡£è¡ççä¸ä¸ºé¢è¯èççãJava é¢è¯çªå»ãV2.0 PDF çæ¬[å ¬ä¼å·](#å ¬ä¼å· "å ¬ä¼å·")åå°åå¤ **"é¢è¯çªå»"** å³å¯å è´¹é¢åï¼ **Java å·¥ç¨å¸å¿ å¤å¦ä¹ èµæº:** ä¸äº Java å·¥ç¨å¸å¸¸ç¨å¦ä¹ èµæºå ¬ä¼å·åå°åå¤å ³é®å **â1â** å³å¯å è´¹æ å¥è·¯è·åã 