5、CountDownLatch原始碼分析
阿新 • • 發佈:2018-12-11
首先看下下面這段程式碼:
package com.mmall.concurrency.example.atomic; import com.mmall.concurrency.annoations.ThreadSafe; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicLong; @Slf4j @ThreadSafe public class AtomicExample2 { // 請求總數 public static int clientTotal = 5000; // 同時併發執行的執行緒數 public static int threadTotal = 200; public static AtomicLong count = new AtomicLong(0); public static void main(String[] args) throws Exception { ExecutorService executorService = Executors.newCachedThreadPool(); final Semaphore semaphore = new Semaphore(threadTotal); final CountDownLatch countDownLatch = new CountDownLatch(clientTotal); for (int i = 0; i < clientTotal; i++) { executorService.execute(() -> { try { semaphore.acquire(); add(); semaphore.release(); } catch (Exception e) { } countDownLatch.countDown(); }); } countDownLatch.await(); executorService.shutdown(); System.out.println("count:{}" + count.get()); } private static void add() { count.incrementAndGet(); // count.getAndIncrement(); } }
1、程式碼中使用了final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);來初始化CountDownLatch物件 2、通過檢視CountDownLatch的該構造方法:主要是對CountDownLatch類中的變數sync進行了初始化的賦值。 3、在使用CountDownLatch的時候,使用的是countDownLatch.countDown();方法,而countDown方法的原始碼如下: 其releaseShared方法明顯是要將sync變數進行減1的操作,但是為了保證原子性,底層原始碼使用瞭如下:首先這裡使用的是一個死迴圈(也就是為什麼說耗效能的原因),迴圈中不斷獲取head的值,而最終break的條件是h==head。所以看其中邏輯,裡面的compareAndSetWaitStatus,這裡就是很有名的CAS的全稱了