Java多線程編程之CountDownLatch同步工具使用實(shí)例
好像倒計(jì)時(shí)計(jì)數(shù)器,調(diào)用CountDownLatch對(duì)象的countDown方法就將計(jì)數(shù)器減1,當(dāng)?shù)竭_(dá)0時(shí),所有等待者就開始執(zhí)行。
java.util.concurrent.CountDownLatch
一個(gè)同步輔助類,在完成一組正在其他線程中執(zhí)行的操作之前,它允許一個(gè)或多個(gè)線程一直等待。用給定的計(jì)數(shù)初始化CountDownLatch。由于調(diào)用了countDown()方法,所以在當(dāng)前計(jì)數(shù)到達(dá)零之前,await方法會(huì)一直受阻塞。之后,會(huì)釋放所有等待的線程,await的所有后續(xù)調(diào)用都將立即返回。這種現(xiàn)象只出現(xiàn)一次——計(jì)數(shù)無(wú)法被重置。如果需要重置計(jì)數(shù),請(qǐng)考慮使用CyclicBarrier。
CountDownLatch是一個(gè)通用同步工具,它有很多用途。將計(jì)數(shù)1初始化的CountDownLatch用作一個(gè)簡(jiǎn)單的開/關(guān)鎖存器,或入口:在通過(guò)調(diào)用countDown()的線程打開入口前,所有調(diào)用await的線程都一直在入口處等待。用N初始化的 CountDownLatch可以使一個(gè)線程在N個(gè)線程完成某項(xiàng)操作之前一直等待,或者使其在某項(xiàng)操作完成N次之前一直等待。
CountDownLatch的一個(gè)有用特性是,它不要求調(diào)用countDown方法的線程等到計(jì)數(shù)到達(dá)零時(shí)才繼續(xù),而在所有線程都能通過(guò)之前,它只是阻止任何線程繼續(xù)通過(guò)一個(gè)await。

舉例:多個(gè)運(yùn)動(dòng)員等待裁判命令:裁判等所有運(yùn)動(dòng)員到齊后發(fā)布結(jié)果
package com.ljq.test.thread;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CountdownLatchTest {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
//裁判發(fā)布命令的計(jì)數(shù)器,計(jì)數(shù)器為0,運(yùn)動(dòng)員就跑
final CountDownLatch cdOrder = new CountDownLatch(1);
//運(yùn)動(dòng)員跑到終點(diǎn)的計(jì)數(shù)器,為0裁判宣布結(jié)果
final CountDownLatch cdAnswer = new CountDownLatch(3);
//產(chǎn)生3個(gè)運(yùn)動(dòng)員
for(int i=0;i<3;i++){
Runnable runnable = new Runnable(){
public void run(){
try {
System.out.println("線程" + Thread.currentThread().getName() + "正準(zhǔn)備接受命令");
cdOrder.await();
System.out.println("線程" + Thread.currentThread().getName() + "已接受命令");
Thread.sleep((long)(Math.random()*10000));
System.out.println("線程" + Thread.currentThread().getName() + "回應(yīng)命令處理結(jié)果");
cdAnswer.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
};
service.execute(runnable); //運(yùn)動(dòng)員開始任務(wù)
}
try {
//裁判休息一會(huì) 再發(fā)布命令
Thread.sleep((long)(Math.random()*10000));
System.out.println("線程" + Thread.currentThread().getName() + "即將發(fā)布命令");
cdOrder.countDown(); //命令計(jì)數(shù)器置為0,發(fā)布命令
System.out.println("線程" + Thread.currentThread().getName() + "已發(fā)送命令,正在等待結(jié)果");
cdAnswer.await(); //等待所有運(yùn)動(dòng)員,計(jì)數(shù)器為0 所有運(yùn)動(dòng)員到位
System.out.println("線程" + Thread.currentThread().getName() + "已收到所有響應(yīng)結(jié)果");
} catch (Exception e) {
e.printStackTrace();
}
service.shutdown();
}
}
返回結(jié)果:
線程pool-1-thread-3正準(zhǔn)備接受命令 線程pool-1-thread-1正準(zhǔn)備接受命令 線程pool-1-thread-2正準(zhǔn)備接受命令 線程main即將發(fā)布命令 線程main已發(fā)送命令,正在等待結(jié)果 線程pool-1-thread-2已接受命令 線程pool-1-thread-1已接受命令 線程pool-1-thread-3已接受命令 線程pool-1-thread-3回應(yīng)命令處理結(jié)果 線程pool-1-thread-2回應(yīng)命令處理結(jié)果 線程pool-1-thread-1回應(yīng)命令處理結(jié)果 線程main已收到所有響應(yīng)結(jié)果
相關(guān)文章
SpringBoot中啟動(dòng)時(shí)如何忽略某項(xiàng)檢測(cè)
這篇文章主要介紹了SpringBoot中啟動(dòng)時(shí)如何忽略某項(xiàng)檢測(cè),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
Java實(shí)現(xiàn)Map集合二級(jí)聯(lián)動(dòng)示例
Java實(shí)現(xiàn)Map集合二級(jí)聯(lián)動(dòng)示例,需要的朋友可以參考下2014-03-03
Java多線程之鎖學(xué)習(xí)(增強(qiáng)版)
這篇文章主要為大家詳細(xì)介紹了Java多線程中鎖的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),對(duì)我們了解線程有一定幫助,需要的可以參考一下2023-02-02
java使用mysql預(yù)編譯語(yǔ)句查詢優(yōu)勢(shì)及示例詳解
這篇文章主要為大家介紹了java使用mysql預(yù)編譯語(yǔ)句的優(yōu)勢(shì)特點(diǎn)及示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
Java中List<T> Map與Map List<T>的區(qū)別小結(jié)
本文主要介紹了Java中List<T> Map與Map List<T>的區(qū)別小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08
java實(shí)現(xiàn)多線程的兩種方式繼承Thread類和實(shí)現(xiàn)Runnable接口的方法
下面小編就為大家?guī)?lái)一篇java實(shí)現(xiàn)多線程的兩種方式繼承Thread類和實(shí)現(xiàn)Runnable接口的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-09-09
java編寫一個(gè)花名隨機(jī)抽取器的實(shí)現(xiàn)示例
這篇文章主要介紹了java編寫一個(gè)花名隨機(jī)抽取器的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03

