日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

【Java 并发编程】CountDownLatch 使用场景示例

發(fā)布時間:2025/6/17 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java 并发编程】CountDownLatch 使用场景示例 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

        • I CountDownLatch 使用場景舉例
        • II CountDownLatch 簡單線程阻塞示例
        • III CountDownLatch 多個線程聯(lián)合阻塞示例



I CountDownLatch 使用場景舉例



1. 單個阻塞等待單個線程 : 初始化 CountDownLatch 時 , 設(shè)置其計數(shù)為 1 , 在線程 A 中調(diào)用 await() 阻塞 , 然后在線程 B 中執(zhí)行操作 , 之后調(diào)用 countDown() 方法 , 計數(shù) - 1 , 線程 A 阻塞解除 ;

2. 單個阻塞等待多個線程 : 初始化 CountDownLatch 時 , 設(shè)置其計數(shù)為 2 , 在線程 A 中調(diào)用 await() 阻塞 ; 然后在線程 B 中執(zhí)行操作 , 調(diào)用 countDown() 方法 , 計數(shù) - 1 ; 同時在線程 C 中執(zhí)行更長時間的操作 , 調(diào)用 countDown() 方法 , 計數(shù) - 1 ; 線程 B 和 C 的操作執(zhí)行完畢后 , 其計數(shù)才減為 0 , 此時線程 A 中的阻塞解除 ;

3. 多個線程阻塞等待單個線程 : 多個線程中調(diào)用 CountDownLatch 對象 await() 方法阻塞 , 在另外一個線程中將計數(shù) countDown() 為 0 , 這些線程即可執(zhí)行 ;

4. 多個線程阻塞等待多個線程 : 多個線程中調(diào)用 CountDownLatch 對象 await() 方法阻塞 , 在另外多個線程中將計數(shù) countDown() 為 0 , 被阻塞這些線程即可執(zhí)行 ;

5. CountDownLatch 使用場景 :

  • ① 單線程等待單線程 : 線程 A 阻塞 , 等待線程 B 執(zhí)行完畢后 , 在執(zhí)行線程 A 操作 ;
  • ② 單線程等待多線程 : 線程 A 阻塞 , 等待線程 B , C , D 等線程執(zhí)行完畢 , 在執(zhí)行線程 A 操作 ;
  • ③ 單線程與多線程互相阻塞 : 線程 B , C , D , 先被 new CountDownLatch ( 1 ) 對象阻塞住 , 在線程 A 中先解除 B , C , D 的阻塞 , 然后 B , C , D 這三個線程才能繼續(xù)執(zhí)行 , 線程 A 解除之后 , 馬上被 new CountDownLatch ( 3 ) 對象阻塞 , B , C , D 三個線程執(zhí)行完后 , 每個線程計數(shù)減一 , 之后解除線程 A 阻塞 , 繼續(xù)執(zhí)行線程 A 的內(nèi)容 ;
  • ④ 單線程與多線程互相阻塞并設(shè)置超時時間 : 在上述 ③ 情況的基礎(chǔ)上 , 加上超時等待 , 如果 B , C , D 線程在指定時間內(nèi)沒有執(zhí)行完畢 , 那么線程 A 也解除阻塞 , 繼續(xù)向下執(zhí)行之后的代碼 ;


II CountDownLatch 簡單線程阻塞示例



1. 代碼說明 : 子線程運(yùn)行后調(diào)用 CountDownLatch 的 await 方法阻塞 , 在主線程中調(diào)用 countDown 方法將計數(shù)減為 0 , 子線程解除阻塞 ;

2. 代碼示例 :

import java.util.concurrent.CountDownLatch;/*** 子線程運(yùn)行后調(diào)用 CountDownLatch 的 await 方法阻塞 ,* 在主線程中調(diào)用 countDown 方法將計數(shù)減為 0 , 子線程解除阻塞*/ public class CountDownLatchDemo {public static void main(String[] args) {System.out.println("1. 主線程 : 開始運(yùn)行 , 創(chuàng)建 CountDownLatch 對象初始計數(shù)為 1");//創(chuàng)建 CountDownLatch 對象 , 初始計數(shù)為 1CountDownLatch countDownLatch = new CountDownLatch(1);System.out.println("2. 主線程 : 創(chuàng)建子線程并運(yùn)行");//創(chuàng)建子線程 , 并設(shè)置其 countDownLatch 對象, 運(yùn)行子線程MyThread myThread = new MyThread(countDownLatch);myThread.start();System.out.println("3. 主線程 : 調(diào)用 countDownLatch.countDown() 方法");countDownLatch.countDown();System.out.println("4. 主線程 : 運(yùn)行結(jié)束");}static class MyThread extends Thread{/*** 用于阻塞的 CountDownLatch 對象*/CountDownLatch countDownLatch;/*** 主線程中傳入 CountDownLatch 對象 , 兩個線程公用一個該對象* @param countDownLatch*/public MyThread(CountDownLatch countDownLatch) {this.countDownLatch = countDownLatch;}@Overridepublic void run() {super.run();try {System.out.println("1. 子線程 : 開始運(yùn)行 , 并調(diào)用 countDownLatch.await() 方法阻塞");//阻塞子線程countDownLatch.await();System.out.println("2. 子線程 : CountDownLatch 對象計數(shù)為 0 , 子線程繼續(xù)運(yùn)行并結(jié)束");} catch (InterruptedException e) {e.printStackTrace();}}}}

3. 執(zhí)行結(jié)果 :

1. 主線程 : 開始運(yùn)行 , 創(chuàng)建 CountDownLatch 對象初始計數(shù)為 1 2. 主線程 : 創(chuàng)建子線程并運(yùn)行 3. 主線程 : 調(diào)用 countDownLatch.countDown() 方法 1. 子線程 : 開始運(yùn)行 , 并調(diào)用 countDownLatch.await() 方法阻塞 4. 主線程 : 運(yùn)行結(jié)束 2. 子線程 : CountDownLatch 對象計數(shù)為 0 , 子線程繼續(xù)運(yùn)行并結(jié)束

III CountDownLatch 多個線程聯(lián)合阻塞示例



1. 情景描述 : 運(yùn)動員賽跑 , 1 個裁判 , 4 個運(yùn)動員 , 4 個運(yùn)動員首先等待裁判發(fā)令 , 才能開始跑 , 裁判發(fā)令后在終點等待 4 個運(yùn)動員都達(dá)到終點后 , 在宣布成績 ;

2. 線程模型分析 :

  • ① 線程 : 裁判員是一個單獨的線程 , 4 個運(yùn)動員是 4 個獨立的線程 ;
  • ② CountDownLatch : 兩種 CountDownLatch 對象 , 一個用于阻塞裁判員線程 , 一個用于阻塞運(yùn)動員線程 ;
  • ③ 運(yùn)動員線程 : 四個運(yùn)動員線程一開始運(yùn)行后 , 馬上調(diào)用 new CountDownLatch(1) 對象阻塞住 , 不能向后運(yùn)行 ;
  • ④ 裁判員線程 : 裁判員線程要等四個運(yùn)動員線程啟動后才能執(zhí)行 , 先調(diào)用 countDown 將四個運(yùn)動員線程取消阻塞 , 然后調(diào)用new CountDownLatch(4) 對象 的 await 阻塞 , 每個運(yùn)動員線程跑到終點后 , 調(diào)用 countDown 方法 , 四個運(yùn)動員全部到達(dá)終點后 , 裁判員解除阻塞 , 宣布成績 ;

3. 代碼示例 :

import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;/*** 情景描述 : 運(yùn)動員賽跑 , 1 個裁判 , 4 個運(yùn)動員 ,* 4 個運(yùn)動員首先等待裁判發(fā)令 , 才能開始跑 ,* 裁判發(fā)令后在終點等待 4 個運(yùn)動員都達(dá)到終點后 , 在宣布成績 ;** 線程模型分析 :** ① 線程 : 裁判員是一個單獨的線程 , 4 個運(yùn)動員是 4 個獨立的線程 ;* ② CountDownLatch : 兩種 CountDownLatch 對象 , 一個用于阻塞裁判員線程 , 一個用于阻塞運(yùn)動員線程 ;* ③ 運(yùn)動員線程 ( 子線程 ) : 四個運(yùn)動員線程一開始運(yùn)行后 , 馬上調(diào)用 new CountDownLatch(1) 對象阻塞住 , 不能向后運(yùn)行 ;* ④ 裁判員線程 ( 主線程 ) : 裁判員線程要等四個運(yùn)動員線程啟動后才能執(zhí)行 , 先調(diào)用 countDown 將四個運(yùn)動員線程取消阻塞 ,* 然后調(diào)用new CountDownLatch(4) 對象 的 await 阻塞 , 每個運(yùn)動員線程跑到終點后 ,* 調(diào)用 countDown 方法 , 四個運(yùn)動員全部到達(dá)終點后 , 裁判員解除阻塞 , 宣布成績 ;*/ public class CountDownLatchDemo {public static void main(String[] args) throws InterruptedException {//用于存儲四個運(yùn)動員的成績int[] grades = new int[4];//四個運(yùn)動員線程的線程池ExecutorService executorService = Executors.newCachedThreadPool();//阻塞運(yùn)動員線程的倒計時鎖對象 , 需要裁判員線程解鎖CountDownLatch runnerLatch = new CountDownLatch(1);//阻塞裁判線程的倒計時鎖對象 , 需要四個運(yùn)動員線程解鎖CountDownLatch judgeLatch = new CountDownLatch(4);//創(chuàng)建并執(zhí)行運(yùn)動員線程 , 使用線程池機(jī)制執(zhí)行for(int i = 0; i < 4; i ++){int finalI = i;//創(chuàng)建運(yùn)動員線程Runnable runnable = new Runnable() {@Overridepublic void run() {try {System.out.println( finalI + " 號運(yùn)動員準(zhǔn)備完畢 , 等待裁判員發(fā)令");runnerLatch.await();System.out.println( finalI + " 號運(yùn)動員起跑");//設(shè)置運(yùn)動員成績 , 這里用一個隨機(jī)數(shù)代替grades[finalI] = (int) (Math.random() * 10000);Thread.sleep(grades[finalI]);//通知裁判員到達(dá)終點judgeLatch.countDown();System.out.println( finalI + " 號運(yùn)動員到達(dá)終點");} catch (InterruptedException e) {e.printStackTrace();}}};//使用線程池調(diào)度運(yùn)行該線程executorService.execute(runnable);}System.out.println("裁判員 : 發(fā)令 , 起跑");//裁判員線程在運(yùn)動員準(zhǔn)備完畢后 , 解除上述 4 個運(yùn)動員線程的阻塞 , 即運(yùn)動員起跑runnerLatch.countDown();System.out.println("裁判員 : 在終點等待 4 名運(yùn)動員");//裁判員線程阻塞, 等待 4 個運(yùn)動員線程執(zhí)行完畢judgeLatch.await();System.out.println("裁判員 : 運(yùn)動員全部到達(dá)終點成績?yōu)?0 號 : " + grades[0] +" , 1 號 : " + grades[1] +" , 2 號 : " + grades[2] +" , 3 號 : " + grades[3]);}}

4. 執(zhí)行結(jié)果 :

裁判員 : 發(fā)令 , 起跑 裁判員 : 在終點等待 4 名運(yùn)動員 2 號運(yùn)動員準(zhǔn)備完畢 , 等待裁判員發(fā)令 2 號運(yùn)動員起跑 1 號運(yùn)動員準(zhǔn)備完畢 , 等待裁判員發(fā)令 1 號運(yùn)動員起跑 0 號運(yùn)動員準(zhǔn)備完畢 , 等待裁判員發(fā)令 0 號運(yùn)動員起跑 3 號運(yùn)動員準(zhǔn)備完畢 , 等待裁判員發(fā)令 3 號運(yùn)動員起跑 1 號運(yùn)動員到達(dá)終點 2 號運(yùn)動員到達(dá)終點 0 號運(yùn)動員到達(dá)終點 3 號運(yùn)動員到達(dá)終點 裁判員 : 運(yùn)動員全部到達(dá)終點成績?yōu)?0 號 : 5601 , 1 號 : 1763 , 2 號 : 4700 , 3 號 : 9650

總結(jié)

以上是生活随笔為你收集整理的【Java 并发编程】CountDownLatch 使用场景示例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。