定義
CountDownLatch是juc下的一個多線程鎖,下面是jdk對它的定義
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
翻譯如下
一種同步輔助工具,允許一個或多個線程等待,直到在其他線程中執行的一組操作完成。
可以簡單地理解為倒計次數鎖,只有計數為零時,才能執行之后的代碼
關鍵api
- 構造方法
public CountDownLatch(int count)
- 倒計數。每執行一次這個方法,計數就減少一次
public void countDown()
- 等待。阻塞方法,如果倒計次數沒有清空,則會一直阻塞,后面的代碼則無法執行
public void await() throws InterruptedException
public boolean await(long timeout, TimeUnit unit)throws InterruptedException
- 獲取當前計數
public long getCount()
應用場景
有一個物業經理,派出手下11個員工去收取物業費,每個員工收費結束交給經理,經理計算手中的總額,大于等于100元,則把交給上級。最后的員工到達后,不論多少,經理都將手中的錢交給上級
EMPLOYEE_COUNT :員工數量
totalAmount :經理手中的金額
THRESHOLD_AMOUNT:門檻金額,當到達門檻金額時,要執行上交操作,totalAmount 清零
feeQueue :使用BlockingQueue阻塞隊列用于存放收取的物業費
代碼如下
private static final int EMPLOYEE_COUNT = 11;
private static final int THRESHOLD_AMOUNT = 100;
private static BlockingQueue<Integer> feeQueue = new ArrayBlockingQueue<>(EMPLOYEE_COUNT);
private static int totalAmount = 0;public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(EMPLOYEE_COUNT + 1);CountDownLatch countDownLatch = new CountDownLatch(EMPLOYEE_COUNT);// 啟動經理線程executorService.execute(() -> {try {while (countDownLatch.getCount() > 0 || !feeQueue.isEmpty()) {Integer amount = feeQueue.poll();if (amount != null) {totalAmount += amount;System.out.println("經理收到了 " + amount + " 元,總金額:" + totalAmount);if (totalAmount >= THRESHOLD_AMOUNT) {System.out.println("經理將 " + totalAmount + " 元交給上級");totalAmount = 0;}}}} catch (Exception e) {Thread.currentThread().interrupt();}});// 啟動員工線程for (int i = 1; i <= EMPLOYEE_COUNT; i++) {final int employeeId = i;executorService.execute(() -> {int amount = (int) (Math.random() * 100) + 1; // 模擬收取隨機金額System.out.println("員工 " + employeeId + " 收取了 " + amount + " 元");try {feeQueue.put(amount);} catch (InterruptedException e) {Thread.currentThread().interrupt();}countDownLatch.countDown();});}// 關閉線程池executorService.shutdown();try {countDownLatch.await(); // 等待所有員工線程完成} catch (InterruptedException e) {Thread.currentThread().interrupt();}// 最后處理剩余金額if (totalAmount > 0) {System.out.println("最后的員工到達后,經理將剩余的 " + totalAmount + " 元交給上級");}
}
輸出結果如下
可以看到經理每收取100元就上交一次,最后的員工到達后,經理將剩余的錢上交了,符合預期
員工 5 收取了 45 元
員工 9 收取了 47 元
員工 11 收取了 24 元
員工 4 收取了 56 元
員工 3 收取了 68 元
員工 7 收取了 11 元
員工 1 收取了 99 元
員工 8 收取了 76 元
員工 10 收取了 30 元
員工 2 收取了 10 元
員工 6 收取了 39 元
最后的員工到達后,經理將剩余的 47 元交給上級
經理收到了 47 元,總金額:47
經理收到了 68 元,總金額:115
經理將 115 元交給上級
經理收到了 45 元,總金額:45
經理收到了 11 元,總金額:56
經理收到了 24 元,總金額:80
經理收到了 99 元,總金額:179
經理將 179 元交給上級
經理收到了 56 元,總金額:56
經理收到了 76 元,總金額:132
經理將 132 元交給上級
經理收到了 30 元,總金額:30
經理收到了 10 元,總金額:40
經理收到了 39 元,總金額:79