Java多線程正確使用倒計時協(xié)調(diào)器CountDownLatch方法詳解
前言
本篇文章的代碼示例已放到 github 上,Git地址為:advance(記錄每一個學習過程),大家把代碼下載下來之后,全局搜索一些關(guān)鍵代碼,即可找到該文章的源碼。
使用場景
想想一個這樣的場景:我要開始吃飯,需要先滿足幾個先決條件:
- 出去買菜
- 開始做飯
- 把做好的飯端上桌
只有滿足這幾個條件之后,我才能真正開始吃飯。同時,這里吃飯的人可能不止我一個人,或許還有我的爸爸媽媽等。
CountDownLatch可以用來實現(xiàn)一個或者多個(注意可以有多個)線程,等待其他線程完全一組特定的操作后,才開始繼續(xù)執(zhí)行的操作,這些特定的操作被稱作先決條件。
基本原理
CountDownLatch內(nèi)部有一個表示未完成的先決條件的計數(shù)器。當某個線程執(zhí)行CountDownLatch.await()時,如果此時的計數(shù)器不為0,那么這個線程就會被阻塞掉。
每當其他線程執(zhí)行CountDownLatch.countDown()時,這個計數(shù)器就會被減為0時,其他被阻塞的線程就會被自動喚醒,執(zhí)行后續(xù)的操作。
常用方法
//構(gòu)造器,定義計數(shù)器的初始值 public CountDownLatch(int count): //阻塞式等待 public void await() //超時自動喚醒式等待 public boolean await(long timeout, TimeUnit unit) //計數(shù)器減1,若此時計數(shù)器為0,則等待的那些線程會被喚醒 public void countDown() //獲取當前計數(shù)器的值 public long getCount()
使用示例
定義買菜的異步線程
public class MaiCaiThread implements Runnable{
private CountDownLatch countDownLatch;
public MaiCaiThread(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("出門買菜回來了");
countDownLatch.countDown();
}
}定義做飯的異步線程
public class ZuoFanThread implements Runnable{
private CountDownLatch countDownLatch;
public ZuoFanThread(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("飯做好了");
countDownLatch.countDown();
}
}定義主線程
public class Main {
static CountDownLatch countDownLatch = new CountDownLatch(2);
public static void main(String[] args) throws InterruptedException {
Thread maicai = new Thread(new MaiCaiThread(countDownLatch));
maicai.start();
Thread zuoFanThread = new Thread(new ZuoFanThread(countDownLatch));
zuoFanThread.start();
System.out.println("我想吃飯了,但是飯還沒做好");
countDownLatch.await();
System.out.println("程序結(jié)束,我吃上飯了");
}
}運行結(jié)果

注意事項
countDownLatch的計數(shù)器不能循環(huán)使用,只能只用一次,若計數(shù)器已經(jīng)減為0,后續(xù)線程盡管調(diào)用await()方法,也不會生效。
如果要循環(huán)使用的話,需要使用CyclicBarrier。
以上就是Java多線程正確使用倒計時協(xié)調(diào)器CountDownLatch的詳細內(nèi)容,更多關(guān)于Java多線程CountDownLatch的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring Boot如何配置內(nèi)置Tomcat的maxPostSize值
這篇文章主要介紹了Spring Boot如何配置內(nèi)置Tomcat的maxPostSize值方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
使用google.kaptcha來生成圖片驗證碼的實現(xiàn)方法
這篇文章主要介紹了使用google.kaptcha來生成圖片驗證碼的實現(xiàn)方法,非常不錯具有一定的參考借鑒價值,需要的朋友可以參考下2018-09-09
基于javamelody監(jiān)控springboot項目過程詳解
這篇文章主要介紹了基于javamelody監(jiān)控springboot項目過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-11-11
解決@Validated注解無效,嵌套對象屬性的@NotBlank無效問題
這篇文章主要介紹了解決@Validated注解無效,嵌套對象屬性的@NotBlank無效問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
Java創(chuàng)建線程的七種方法總結(jié)(全網(wǎng)最全面)
線程是Java中的基本執(zhí)行單元,它允許程序在同一時間執(zhí)行多個任務,下面這篇文章主要給大家總結(jié)介紹了關(guān)于Java創(chuàng)建線程的七種方法,文中通過實例代碼將這七種方法介紹的非常詳細,需要的朋友可以參考下2023-05-05
詳解Spring Boot 中實現(xiàn)定時任務的兩種方式
這篇文章主要介紹了Spring Boot 中實現(xiàn)定時任務的兩種方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-04-04
基于Jenkins自動打包并部署docker環(huán)境的操作過程
這篇文章主要介紹了基于Jenkins自動打包并部署docker環(huán)境,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08

