最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的CountDownLatch源碼解析

 更新時間:2023年12月22日 09:59:06   作者:正經(jīng)人z.  
這篇文章主要介紹了Java中的CountDownLatch源碼解析,CountDownLatch類是一個同步輔助裝置,允許一個或多個線程去等待直到另外的線程完成了一組操作,需要的朋友可以參考下

一、簡介

1、CountDownLatch類是一個同步輔助裝置,允許一個或多個線程去等待直到另外的線程完成了一組操作。

2、它通過count進行初始化,await方法會阻塞直到當前的count為0由于調(diào)用了countDown方法,之后所有的線程將被釋放并且立即返回結(jié)果。count不能被重置,如果你想count可以重置,請使用CyclicBarrier

3、CountDownLatch是一個通用的同步工具,可用于多種用途。CountDownLatch初始化使用count作為一個簡單的可開可關(guān)的大門:所有的線程調(diào)用await方法等待在大門里,當一個線程調(diào)用了countDown方法后大門打開

二、源碼分析

 public class CountDownLatch {
        //內(nèi)部類Sync繼承了AQS
        private static final class Sync extends AbstractQueuedSynchronizer {
            private static final long serialVersionUID = 4982264981922014374L;
            //構(gòu)造方法中的count其實就是傳給了AQS的state屬性
            Sync(int count) {
                setState(count);
            }
            //得到的AQS的state屬性值
            int getCount() {
                return getState();
            }
            //重寫的AQS的tryAcquireShared,在共享模式的情況下獲取鎖
            protected int tryAcquireShared(int acquires) {
                //獲取鎖的前提是state為0,表示當前未被其他線程占有
                return (getState() == 0) ? 1 : -1;
            }
            //重寫的AQS的tryReleaseShared,在共享模式下釋放鎖
            protected boolean tryReleaseShared(int releases) {
                // 減count; 當count為0時喚醒
                for (;;) {
                    int c = getState();
                    if (c == 0)  //表示釋放鎖的前提是占有鎖,也就是state的屬性值大于0
                        return false;
                    int nextc = c-1;  //state的值減1
                    if (compareAndSetState(c, nextc))  //利用CAS來改變state的值
                        return nextc == 0;  //當state的值為0時返回true
                }
            }
        }
        private final Sync sync;
        /**
         * 通過count初始化一個CountDownLatch
         *
         *在線程調(diào)用await方法后如果想通過,必須執(zhí)行count次countDown方法
         * @如果count為負數(shù),則拋出IllegalArgumentException
         */
        public CountDownLatch(int count) {
            if (count < 0) throw new IllegalArgumentException("count < 0");
            this.sync = new Sync(count);
        }
    ================================================================================================
    				兩個核心方法,其實底層使用的AQS的方法(共享模式下)
        /**
         * 調(diào)用await方法會使當前的線程等待除非count的數(shù)值降為0或者中間拋出異常
         *
         * 如果當前的count為0,則該方法立即返回
         *
         *如果當前的count大于0,則當前線程因線程調(diào)度目的而被禁用,并且休眠,直到發(fā)生以下兩種情況之一:
         *1、調(diào)用countDown方法將count的值降為0
         *2、其他的線程打斷了當前線程,使用Thread.interrupted
         */
        public void await() throws InterruptedException {
            sync.acquireSharedInterruptibly(1);
        }
        /**
         *減count的值,如果count的值為0了,則釋放所有等待的線程
         *
         *如果當前的count值大于0,那么它是被減了。
         *如果當前的count值等于0,那么所有等待的線程被喚醒接受線程的調(diào)度
         */
        public void countDown() {
            sync.releaseShared(1);
        }
    ================================================================================================
        /**
    	 *返回count的值,用于調(diào)試或者測試
         */
        public long getCount() {
            return sync.getCount();
        }

三、小練習(xí)-模擬王者榮耀單挑

public static void main(String[] args) throws Exception{
        CountDownLatch cd = new CountDownLatch(3);
        Thread beginGame = new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    cd.await();
                    System.out.println("歡迎來到王者榮耀,敵軍還有30秒到達戰(zhàn)場============");
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        },"beginGame");
        Thread player1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    System.out.println("玩家一以準備=======");
                    cd.countDown();
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        },"player1");
        Thread player2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    System.out.println("玩家二以準備=======");
                    cd.countDown();
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        },"player2");
        beginGame.start();
        player1.start();
        player2.start();
    }

四、總結(jié)

1、請注意,只有在共享模式下才能使用CountDownLatch,因為只有在共享模式下,AQS的state屬性的值才有可能大于1,才有后續(xù)的等待state的值為0,其他的線程才能被喚醒繼續(xù)執(zhí)行的可能,這里針對的多個線程等待!

2、CountDownLatch里面有兩個核心方法:await和countDown。這里注意,await和平時學(xué)習(xí)的Condition中的await不一樣,這里的await就是線程獲取鎖且必須在state值為0,也就是該資源未被占有的情況下,獲取鎖成功后state的值從0變?yōu)?,表示該線程持有了該資源的鎖。countDown就是將state的屬性值減1。這兩個方法其實都是調(diào)用的AQS的方法執(zhí)行的。

3、初始化傳入的count表示的就是AQS的state屬性的值,可以理解為持有該資源的線程數(shù),其他的線程想要拿到這個資源,必須等到該資源的state的值變?yōu)?才能被喚醒去獲取鎖。也說明了如果該state的值要從N變?yōu)?,需要執(zhí)行N次countDown方法

4、有點類似于線程通信機制的wait/notify。

5、CountDownLatch典型的用法是將一個程序分為n個互相獨立的可解決任務(wù),并創(chuàng)建值為n的CountDownLatch。當每一個任務(wù)完成時,都會在這個鎖存器上調(diào)用countDown,等待問題被解決的任務(wù)調(diào)用這個鎖存器的await,將他們自己攔住,直至鎖存器計數(shù)結(jié)束。

6、個人理解:線程A和線程B爭奪一個資源,且線程B需要在線程A之后才能執(zhí)行,線程A首先拿到這個資源,然后線程A需要執(zhí)行一個大任務(wù),這個大任務(wù)可以分解為N個小任務(wù),所以,創(chuàng)建一個N的count的CountDownLatch,所以,state的值就是N了,線程A每執(zhí)行完一個小任務(wù)后,將調(diào)用CountDownLatch的countDown方法將state的值減1,直到最后,所有的小任務(wù)執(zhí)行完畢,代表線程A的大任務(wù)也就執(zhí)行完畢了,此時,該資源的state的值為0了,代表可以被其他線程爭奪獲取鎖。線程B就可以調(diào)用countDown的await就能夠獲取該資源的鎖,并將state的值變?yōu)?。

到此這篇關(guān)于Java中的CountDownLatch源碼解析的文章就介紹到這了,更多相關(guān)CountDownLatch源碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 23種設(shè)計模式(1) java單例模式

    23種設(shè)計模式(1) java單例模式

    這篇文章主要為大家詳細介紹了23種設(shè)計模式之java單例模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • java實現(xiàn)Composite組合模式的實例代碼

    java實現(xiàn)Composite組合模式的實例代碼

    這篇文章主要介紹了java實現(xiàn)Composite組合模式,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • Java中的Semaphore信號量使用方法代碼實例

    Java中的Semaphore信號量使用方法代碼實例

    這篇文章主要介紹了Java中的Semaphore信號量使用方法代碼實例,Semaphore是一種基于計數(shù)的信號量,它可以設(shè)定一個閾值,基于此,多個線程競爭獲取許可信號,做自己的申請后歸還,超過閾值后,線程申請許可信號將會被阻塞,需要的朋友可以參考下
    2023-11-11
  • 一文帶你搞懂Java中的遞歸

    一文帶你搞懂Java中的遞歸

    這篇文章主要為大家詳細介紹了Java中的遞歸的實現(xiàn)以及應(yīng)用,文中的示例代碼講解詳細,對我們學(xué)習(xí)Java有一定幫助,需要的可以參考一下
    2022-10-10
  • SpringCloud無法獲取Nacos中的配置文件信息解決方案

    SpringCloud無法獲取Nacos中的配置文件信息解決方案

    文章介紹了在項目啟動時解決@Value占位符值找不到問題的步驟,包括檢查版本號、添加依賴、檢查配置文件優(yōu)先級以及正確配置dataID
    2025-12-12
  • 詳解Flutter TabLayout 布局用法

    詳解Flutter TabLayout 布局用法

    Flutter是谷歌的移動UI框架,可以快速在iOS和Android上構(gòu)建高質(zhì)量的原生用戶界面。這篇文章主要介紹了Flutter TabLayout 布局用法,需要的朋友可以參考下
    2019-07-07
  • Java命名規(guī)范

    Java命名規(guī)范

    本文主要介紹了Java命名規(guī)范。具有一定的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • MyBatis插入時獲取自增主鍵方法

    MyBatis插入時獲取自增主鍵方法

    MyBatis 3.2.6插入時候獲取自增主鍵方法有兩種,下面以以MySQL5.5為例通過兩種方法給大家介紹mybatis獲取自增主鍵的方法,一起看看吧
    2016-11-11
  • java 容器的快速失敗(fast-fail)機制

    java 容器的快速失敗(fast-fail)機制

    Java容器的快速失敗機制是一種在迭代過程中檢測并處理集合并發(fā)修改的特性,該機制適用于ArrayList、HashMap等集合類,本文就來介紹一下java 容器的快速失敗(fast-fail)機制,感興趣的可以了解一下
    2024-11-11
  • 使用Lombok導(dǎo)致打印的tostring中缺少父類的屬性問題

    使用Lombok導(dǎo)致打印的tostring中缺少父類的屬性問題

    使用Lombok時,若發(fā)現(xiàn)@Data注解的@ToString不包含父類屬性,可通過添加@ToString(callSuper=true)解決,此方法確保在生成toString()時包括父類的屬性,有效解決只打印子類屬性的問題,這種做法對于需要完整信息展示的場景尤為重要
    2024-11-11

最新評論

苗栗县| 马山县| 全州县| 武穴市| 吴忠市| 辛集市| 巩义市| 虞城县| 哈密市| 新源县| 视频| 东乌珠穆沁旗| 德安县| 临高县| 安顺市| 卢氏县| 桓台县| 龙海市| 尤溪县| 娱乐| 闽侯县| 苗栗市| 潢川县| 大洼县| 高碑店市| 旬阳县| 本溪市| 建水县| 廉江市| 忻城县| 盘锦市| 修武县| 丰台区| 黑河市| 延长县| 军事| 柞水县| 寿阳县| 洪雅县| 抚顺市| 铁力市|