java.util.concurrent(J.U.C)大大提升了併發性能,AQS 被認爲是 J.U.C 的核心。java
CountdownLatch
用來控制一個線程等待多個線程。併發
維護了一個計數器 cnt,每次調用 countDown() 方法會讓計數器的值減 1,減到 0 的時候,那些由於調用 await() 方法而在等待的線程就會被喚醒。分佈式
public class CountdownLatchExample { public static void main(String[] args) throws InterruptedException { final int totalThread = 10; CountDownLatch countDownLatch = new CountDownLatch(totalThread); ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < totalThread; i++) { executorService.execute(() -> { System.out.print("run.."); countDownLatch.countDown(); }); } countDownLatch.await(); System.out.println("end"); executorService.shutdown(); } }
run..run..run..run..run..run..run..run..run..run..end
CyclicBarrier
用來控制多個線程互相等待,只有當多個線程都到達時,這些線程纔會繼續執行。函數
和 CountdownLatch 類似,都是經過維護計數器來實現的。線程執行 await() 方法以後計數器會減 1,並進行等待,直到計數器爲 0,全部調用 await() 方法而在等待的線程才能繼續執行。高併發
CyclicBarrier 和 CountdownLatch 的一個區別是,CyclicBarrier 的計數器經過調用 reset() 方法能夠循環使用,因此它才叫作循環屏障。性能
CyclicBarrier 有兩個構造函數,其中 parties 指示計數器的初始值,barrierAction 在全部線程都到達屏障的時候會執行一次。ui
public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction; } public CyclicBarrier(int parties) { this(parties, null); } public class CyclicBarrierExample { public static void main(String[] args) { final int totalThread = 10; CyclicBarrier cyclicBarrier = new CyclicBarrier(totalThread); ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < totalThread; i++) { executorService.execute(() -> { System.out.print("before.."); try { cyclicBarrier.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } System.out.print("after.."); }); } executorService.shutdown(); } }
before..before..before..before..before..before..before..before..before..before..after..after..after..after..after..after..after..after..after..after..
Semaphore
Semaphore 相似於操做系統中的信號量,能夠控制對互斥資源的訪問線程數。this
如下代碼模擬了對某個服務的併發請求,每次只能有 3 個客戶端同時訪問,請求總數爲 10。spa
public class SemaphoreExample { public static void main(String[] args) { final int clientCount = 3; final int totalRequestCount = 10; Semaphore semaphore = new Semaphore(clientCount); ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < totalRequestCount; i++) { executorService.execute(()->{ try { semaphore.acquire(); System.out.print(semaphore.availablePermits() + " "); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } }); } executorService.shutdown(); } }
2 1 2 2 2 2 2 1 2 2
免費Java高級資料須要本身領取,涵蓋了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高併發分佈式等教程,一共30G。
傳送門:https://mp.weixin.qq.com/s/Jz...操作系統