CountDownLatch同步工具類使用詳解
CountDownLatch 使用說明,供大家參考,具體內(nèi)容如下
CountDownLatch是一種java.util.concurrent包下一個(gè)同步工具類,它允許一個(gè)或多個(gè)線程等待直到在其他線程中一組操作執(zhí)行完成。
CountDownLatch的用法非常簡單,下面的例子也是我在網(wǎng)上看到的,十分貼切,這里就貼出來
public class Test {
public static void main(String[] args) {
CountDownLatch begin = new CountDownLatch(1);
CountDownLatch end = new CountDownLatch(2);
for(int i=0; i<2; i++){
Thread thread = new Thread(new Player(begin,end));
thread.start();
}
try{
System.out.println("the race begin");
begin.countDown();
end.await();
System.out.println("the race end");
}catch(Exception e){
e.printStackTrace();
}
}
}
/**
* 選手
*/
class Player implements Runnable{
private CountDownLatch begin;
private CountDownLatch end;
Player(CountDownLatch begin,CountDownLatch end){
this.begin = begin;
this.end = end;
}
public void run() {
try {
begin.await();
System.out.println(Thread.currentThread().getName() + " arrived !");;
end.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
下面是運(yùn)行結(jié)果

可以看到 通過CountDownLatch 的使用 我們控制了線程的執(zhí)行順序。
在上面代碼中,我們使用到await()方法 和 countDown() 方法 。我們驗(yàn)證一下它們各自的作用。
首先 驗(yàn)證await() 方法。將main方法中的end.await() 注釋掉,下面是注釋掉后的運(yùn)行結(jié)果

可以看到主線程沒有等待代表選手的線程結(jié)束,直接宣布比賽結(jié)束了!剛開始就結(jié)束的比賽- -
這里可以看出,await() 方法具有阻塞作用
其次 我們來驗(yàn)證countDown方法,將代表選手線程中的end.countDown() 進(jìn)行注釋,下面是運(yùn)行結(jié)果

程序一直在運(yùn)行,所有選手都已經(jīng)到了終點(diǎn),但是裁判就是不宣傳比賽結(jié)束,他在等什么呢?
我們猜測countDown() 方法具有喚醒阻塞線程的作用。
那我們也許會(huì)問,既然有喚醒阻塞線程的作用,那么我們只調(diào)用一次countDown() 方法不就是可以喚醒被阻塞的主線程了嗎?
我們試一下,取消上面coutDown()的注釋,再次創(chuàng)建一個(gè)選手,代碼如下
class Player2 implements Runnable{
private CountDownLatch begin;
private CountDownLatch end;
Player2(CountDownLatch begin,CountDownLatch end){
this.begin = begin;
this.end = end;
}
public void run() {
try {
begin.await();
System.out.println(Thread.currentThread().getName() + " arrived !");
// end.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
main 方法也修改如下,創(chuàng)建了兩個(gè)不同的選手
public static void main(String[] args)
{
CountDownLatch begin = new CountDownLatch(1);
CountDownLatch end = new CountDownLatch(2);
Thread thread = new Thread(new Player(begin, end));
thread.start();
Thread thread2 = new Thread(new Player2(begin, end));
thread2.start();
try
{
System.out.println("the race begin");
begin.countDown();
end.await();
System.out.println("the race end");
}
catch (Exception e)
{
e.printStackTrace();
}
}
運(yùn)行一下,下面是結(jié)果

主程序一直阻塞,沒有被喚醒,裁判上廁所上得有點(diǎn)久?。?/p>
這樣看來countDown() 并不是直接喚醒線程,有點(diǎn)像一個(gè)計(jì)數(shù)器,倒計(jì)時(shí)的那種。
查看API文檔,果然,我們在構(gòu)造函數(shù)中添加了參數(shù)2,就需要調(diào)用 2 次 countDown() 才能將 end.await() 阻塞的線程喚醒。
CountDownLatch end = new CountDownLatch(2);
總結(jié)一下,
1、CountDownLatch end = new CountDownLatch(N); //構(gòu)造對(duì)象時(shí)候 需要傳入?yún)?shù)N
2、end.await() 能夠阻塞線程 直到調(diào)用N次end.countDown() 方法才釋放線程
3、end.countDown() 可以在多個(gè)線程中調(diào)用 計(jì)算調(diào)用次數(shù)是所有線程調(diào)用次數(shù)的總和
下一篇博客,我將從源碼層面說明 CountDownLatch 的工作原理。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot整合EasyCaptcha實(shí)現(xiàn)圖形驗(yàn)證碼功能
這篇文章主要介紹了SpringBoot整合EasyCaptcha實(shí)現(xiàn)圖形驗(yàn)證碼功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-02-02
Java?IO網(wǎng)絡(luò)模型實(shí)現(xiàn)解析
這篇文章主要為大家介紹了Java?IO網(wǎng)絡(luò)模型實(shí)現(xiàn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
詳解Spring Cloud Alibaba Sidecar多語言微服務(wù)異構(gòu)
這篇文章主要介紹了詳解Spring Cloud Alibaba Sidecar多語言微服務(wù)異構(gòu),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
郵件收發(fā)原理你了解嗎? 郵件發(fā)送基本過程與概念詳解(一)
你真的了解郵件收發(fā)原理嗎?這篇文章主要為大家詳細(xì)介紹了郵件發(fā)送基本過程與概念,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
feign的ribbon超時(shí)配置和hystrix的超時(shí)配置說明
這篇文章主要介紹了feign的ribbon超時(shí)配置和hystrix的超時(shí)配置說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09
SpringBoot中使用spring-retry 解決失敗重試調(diào)用
本文主要介紹了SpringBoot中使用spring-retry 解決失敗重試調(diào)用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07

