Java中CountDownLatch進行多線程同步詳解及實例代碼
Java中CountDownLatch進行多線程同步詳解
CountDownLatch介紹
在前面的Java學(xué)習(xí)筆記中,總結(jié)了Java中進行多線程同步的幾個方法:
1、synchronized關(guān)鍵字進行同步。
2、Lock鎖接口及其實現(xiàn)類ReentrantLock、ReadWriteLock鎖實現(xiàn)同步。
3、信號量Semaphore實現(xiàn)同步。
其中,synchronized關(guān)鍵字和Lock鎖解決的是多個線程對同一資源的并發(fā)訪問問題。信號量Semaphore解決的是多副本資源的共享訪問問題。
今天,來學(xué)習(xí)一下Java中的另外一個多線程同步輔助類:CountDownLatch。官方文檔對CountDownLatch的解釋是:在完成一組正在其他線程中執(zhí)行的操作之前,它允許一個或多個線程一直等待。也就是說,CountDownLatch控制某個或者多個線程,讓它們等待多個線程完成某項任務(wù)后,再啟動。CountDownLatch主要是用來同步多個任務(wù)的執(zhí)行,區(qū)別于其他的synchronized關(guān)鍵字,鎖,信號量是用來同步共享資源的。
CountDownLatch實現(xiàn)原理簡介:
CountDownLatch內(nèi)部維護一個計數(shù)器,計數(shù)器的值為待完成的任務(wù)數(shù)N,需要等待這N個任務(wù)完成的線程調(diào)用
CountDownLatch的await()方法使自己進入休眠等待狀態(tài)。
當某一個任務(wù)線程完成某一個任務(wù)后調(diào)用CountDownLatch的countDown()方法來表示自己的任務(wù)已完成,此時CountDownLatch的計數(shù)器值減1,當所有的任務(wù)完成式,計數(shù)器的值為0。當計數(shù)器值為0時,CountDownLatch將喚醒所有因await()方法進入休眠的線程。
CountDownLatch的使用:
CountDownLatch的使用主要有3點:
1、CountDownLatch的聲明及初始化,在初始化時需要指定等待完成的任務(wù)數(shù)。
2、某一個任務(wù)完成時調(diào)用CountDownLatch的countDown()方法,向CountDownLatch報告自己的任務(wù)已經(jīng)完成,
3、需要等待任務(wù)完成的線程調(diào)用CountDownLatch的await()方法,調(diào)用后該線程將進入休眠,并在所有任務(wù)數(shù)完成后CountDownLatch的計數(shù)器值為0時,因await()方法進行休眠的線程將被喚醒。
在此本人在Java 7并發(fā)編程實戰(zhàn)手冊該書中的CountDownLatch使用示例的基礎(chǔ)上做了部分改進,來演示CountDownLatch的使用詳情:
模擬10個參會者和一個主持人參加的一個會以,每個參會者及主持人需要等待其他的參會者均到場簽到之后,才能開始會以并發(fā)言。為此,先創(chuàng)建一個會以管理的類VideoConference,其提供一個arrive()方法供參會者調(diào)用來進行簽到。會議管理的擁有者是主持人,其等待每個參會者的簽到:
public class VideoConference implements Runnable{
private final CountDownLatch countDownLatch;
private int number;
public VideoConference(int number) {
this.number = number;
this.countDownLatch = new CountDownLatch(number);//使用Number初始化其內(nèi)部的計數(shù)器,當初始化完成后,不能再次初始化
}
public void arrive(String name){
//每個需要同步的任務(wù),在任務(wù)完成時,需要調(diào)用該方法
countDownLatch.countDown();//countDownLatch內(nèi)部的計數(shù)器減1
System.out.print("arrive:"+name+"\n");
try{
countDownLatch.await();//await方法是線程進入休眠,當countDownLatch計數(shù)器為0時,將被喚醒
//線程被喚醒,在這里可以執(zhí)行一系列任務(wù)
System.out.print("name:"+name + " say:let's start..." +"\n");
}catch (InterruptedException e){
e.printStackTrace();
}
}
public void run(){
System.out.print("has arrive:"+(number-countDownLatch.getCount())+"\n");
try{
countDownLatch.await();//await方法是線程進入休眠,當countDownLatch計數(shù)器為0時,將被喚醒
//線程被喚醒,在這里可以執(zhí)行一系列任務(wù)
System.out.print("all arrived:"+(number-countDownLatch.getCount())+"\n");
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
創(chuàng)建一個參會者類Participant:
public class Participant implements Runnable{
private VideoConference videoConference;
private String name;
public Participant(String name, VideoConference videoConference) {
this.name = name;
this.videoConference = videoConference;
}
public void run(){
try {
//do something
Thread.sleep(50);
//
videoConference.arrive(name);
}catch (InterruptedException e){
e.printStackTrace();
}
}
public static void main(String[] args){
VideoConference videoConference = new VideoConference(10);
Thread videoThread = new Thread(videoConference);
videoThread.start();
for(int i=0; i<10; i++){
Thread thread = new Thread(new Participant("participant:"+i,videoConference));
thread.start();
}
}
}
Participant類中的main函數(shù)首先創(chuàng)建了一個需要10個參會者參加的一個會議,之后,創(chuàng)建了10個參會者并逐個簽到,在10個參會者都簽到之后,每個參會者及主持人將被"喚醒"并發(fā)言。
總結(jié):
CountDownLatch類解決的是多線程間的同步等待、任務(wù)協(xié)調(diào)問題,應(yīng)用在如在啟動某個程序的主功能前,需要前置完成配置環(huán)境檢查、網(wǎng)絡(luò)檢查等多個子任務(wù)等類似的場景。在Java中,除了使用CountDownLatch來實現(xiàn)多線程間的同步等待以外,還可以使用柵欄技術(shù)CyclicBarrier來實現(xiàn)多線程間的同步等待、任務(wù)協(xié)調(diào)。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
- java多線程CountDownLatch與線程池ThreadPoolExecutor/ExecutorService案例
- Java countDownLatch如何實現(xiàn)多線程任務(wù)阻塞等待
- 如何使用CountDownLatch同步j(luò)ava多線程
- java使用CountDownLatch等待多線程全部執(zhí)行完成
- JAVA多線程CountDownLatch使用詳解
- Java中多線程同步類 CountDownLatch
- 詳解Java多線程編程中CountDownLatch阻塞線程的方法
- Java多線程編程之CountDownLatch同步工具使用實例
- Java多線程之同步工具類CountDownLatch
相關(guān)文章
Java中JSONObject與JSONArray的使用區(qū)別詳解
這篇文章主要介紹了Java中JSONObject與JSONArray的使用區(qū)別詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11
JDBC PreparedStatement Like參數(shù)報錯解決方案
這篇文章主要介紹了JDBC PreparedStatement Like參數(shù)報錯解決方案,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10
springboot集成redis并使用redis生成全局唯一索引ID
本文主要介紹了springboot集成redis并使用redis生成全局唯一索引ID,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03
IntelliJ IDEA基于Maven構(gòu)建Java項目
在 Java 開發(fā)中,使用 Maven 是一種廣泛采用的構(gòu)建工具,本文主要介紹了IntelliJ IDEA基于Maven構(gòu)建Java項目,具有一定的參考價值,感興趣的可以了解一下2024-03-03
java中@JsonValue和@JsonCreator使用
本文主要介紹了java中@JsonValue和@JsonCreator使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-06-06
SpringBoot @PostConstruct原理用法解析
這篇文章主要介紹了SpringBoot @PostConstruct原理用法解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-08-08
Spring?Security短信驗證碼實現(xiàn)詳解
本文主要介紹了Spring?Security短信驗證碼的實現(xiàn)詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-11-11
Java實現(xiàn)給圖片添加圖片水印,文字水印及馬賽克的方法示例
這篇文章主要介紹了Java實現(xiàn)給圖片添加圖片水印,文字水印及馬賽克的方法,涉及java針對圖片的讀取、水印添加、馬賽克設(shè)置等相關(guān)操作技巧,需要的朋友可以參考下2018-01-01

