Java中的共享鎖CountDownLatch及源碼解析
前言
CountDownLatch是一種同步輔助工具,允許一個(gè)或多個(gè)線程等待,直到在其它線程中執(zhí)行的一組操作完成;CountDownLatch使用指定的計(jì)數(shù)初始化。
wait方法會(huì)阻塞,直到當(dāng)前計(jì)數(shù)由于countDown方法的調(diào)用而達(dá)到零,之后所有的等待線程都會(huì)被釋放,任何后續(xù)的wait調(diào)用都會(huì)立即返回。這是一種一次性現(xiàn)象,計(jì)數(shù)無法重置。如果需要重置計(jì)數(shù)的版本,可以參考CyclicBarrier。
一、CountDownLatch的使用方法
public class Test {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("線程一執(zhí)行完成");
latch.countDown();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("線程二執(zhí)行完成");
latch.countDown();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("線程三執(zhí)行完成");
latch.countDown();
}
}).start();
System.out.println("主線程等待");
latch.await();
System.out.println("主線程開始執(zhí)行");
}
}
執(zhí)行結(jié)果如下:
線程三執(zhí)行完成
主線程等待
線程二執(zhí)行完成
線程一執(zhí)行完成
主線程開始執(zhí)行
上面的示例是一個(gè)主線程等待其它三個(gè) 線程執(zhí)行,執(zhí)行完成后調(diào)用countDown方法,計(jì)數(shù)減一,直到所有的線程執(zhí)行完成,計(jì)數(shù)歸0,然后await方法放回,主線程繼續(xù)執(zhí)行。
二、CountDownLatch源碼解析
public void countDown() {
sync.releaseShared(1);
}
countDown方法會(huì)遞減鎖的計(jì)數(shù)器,如果計(jì)數(shù)為0,則釋放所有等待的線程。如果當(dāng)前計(jì)數(shù)大于0,則遞減。如果新計(jì)數(shù)為0,則出于線程調(diào)度的目的重新啟用所有等待線程。如果當(dāng)前計(jì)數(shù)等于0,那么什么也不發(fā)生。
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
await方法會(huì)使當(dāng)前線程等待,直到鎖的計(jì)數(shù)器為0,除非線程被中斷。如果當(dāng)前計(jì)數(shù)為0,則此方法立即返回。如果當(dāng)前計(jì)數(shù)大于0,則出于線程調(diào)度目的,當(dāng)前線程將被禁用,并處于休眠狀態(tài),直到發(fā)生一下兩種情況之一:
1.由于調(diào)用了countDown方法,計(jì)數(shù)達(dá)到了0;
2.其它線程終端當(dāng)前線程;
到此這篇關(guān)于Java中的共享鎖CountDownLatch及源碼解析的文章就介紹到這了,更多相關(guān)Java中的共享鎖CountDownLatch內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java如何實(shí)現(xiàn)基于opencv全景圖合成實(shí)例代碼
全景圖相信大家應(yīng)該都不陌生,下面這篇文章主要給大家介紹了關(guān)于java如何實(shí)現(xiàn)基于opencv全景圖合成的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07
SpringBoot與gRPC2.0集成的實(shí)現(xiàn)示例
本文主要介紹了SpringBoot與gRPC2.0集成,包括HTTP/2支持、ProtocolBuffers增強(qiáng)、服務(wù)定義改進(jìn)等內(nèi)容,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2026-04-04
Java中Executor和Executors的區(qū)別小結(jié)
在Java并發(fā)編程中,Executor是一個(gè)核心接口,提供了任務(wù)執(zhí)行的抽象方法,而Executors是一個(gè)工具類,提供了創(chuàng)建各種線程池的工廠方法,Executor關(guān)注任務(wù)的執(zhí)行,而Executors關(guān)注如何創(chuàng)建適合的執(zhí)行器,感興趣的可以了解一下2024-10-10
Java Lambda表達(dá)式和函數(shù)式接口實(shí)例分析
這篇文章主要介紹了Java Lambda表達(dá)式和函數(shù)式接口,結(jié)合實(shí)例形式分析了Java8 Lambda表達(dá)式和函數(shù)式接口相關(guān)原理、用法及操作注意事項(xiàng),需要的朋友可以參考下2019-09-09
feign遠(yuǎn)程調(diào)用無法傳遞對象屬性405的問題
這篇文章主要介紹了feign遠(yuǎn)程調(diào)用無法傳遞對象屬性405的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
簡單實(shí)現(xiàn)java抽獎(jiǎng)系統(tǒng)
這篇文章主要教大家如何簡單實(shí)現(xiàn)java抽獎(jiǎng)系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
SpringCloud Alibaba Seata (收藏版)
Seata是一款開源的分布式事務(wù)解決方案,致力于在微服務(wù)架構(gòu)在提供高性能和簡單一樣的分布式事務(wù)服務(wù)。這篇文章主要介紹了SpringCloud Alibaba Seata 的相關(guān)知識,需要的朋友可以參考下2020-10-10
SpringBoot中集成串口通信的項(xiàng)目實(shí)踐
本文主要介紹了SpringBoot中集成串口通信,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08

