亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JUC系列學(xué)習(xí)工具類CountDownLatch詳解

 更新時(shí)間:2022年08月18日 09:05:49   作者:劍圣無(wú)痕  
這篇文章主要介紹了JUC系列學(xué)習(xí)工具類CountDownLatch詳解,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可任意參考一下

前言:

項(xiàng)目中我們經(jīng)常會(huì)遇到有時(shí)候需要等待其他線程完成任務(wù)后,主線程才能執(zhí)行其他任務(wù),那么我們將如何實(shí)現(xiàn)呢?

Join 解決方案

join 的工作原理是,檢查thread是否存活,如果存活則讓當(dāng)前線程永遠(yuǎn)wait,直到 thread線程終止,線程的 notifyAll才會(huì)被調(diào)用。

具體實(shí)現(xiàn)

public class JoinAThread extends Thread
{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + 
                " 線程開(kāi)始");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
         System.out.println( Thread.currentThread().getName() + 
                " 線程執(zhí)行完畢");
    }
}

public class JoinBThread extends Thread
{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + 
                " 線程開(kāi)始");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
         System.out.println( Thread.currentThread().getName() + 
                " 線程執(zhí)行完畢");
    }
}

public class JoinTest
{
   public static void main(String[] args) throws InterruptedException
{
       JoinAThread joinA =new JoinAThread();
       Thread threadA =new Thread(joinA,"線程A");

       JoinBThread joinB =new JoinBThread();
       Thread threadB =new Thread(joinB,"線程B");
       threadA.start();
       threadB.start();
       threadA.join();
       threadB.join();

       System.out.println("子線程執(zhí)行完成了,主線程"+Thread.currentThread().getName()+"開(kāi)始執(zhí)行了");
     }
}

執(zhí)行結(jié)果

從結(jié)果中,我們可以看出只有子線程執(zhí)行完成了,主線程才開(kāi)始執(zhí)行。join的實(shí)現(xiàn)我們需要每個(gè)線程進(jìn)行join,如果存在多個(gè)線程,那么寫(xiě)起來(lái)會(huì)比較的繁瑣,那么又沒(méi)更新優(yōu)化的方案了,答案是JUC下面的工具類CountDownLatch,也能完成同樣的功能。

CountDownLatch 解決方案

具體實(shí)現(xiàn)

public class CountDownLatchTest
{
    private static Logger logger =LoggerFactory.getLogger(CountDownLatchTest.class);
    public static void main(String[] args) throws InterruptedException
    {
        ExecutorService exec = Executors.newCachedThreadPool();
        final CountDownLatch countDownLatch = new CountDownLatch(10);
        for (int i = 1; i <= 10; i++){
            exec.execute(() -> {
                try {
                    invokeServiec();
                } catch (InterruptedException e) 
                {
                    logger.info("invoce service error",e);
                }
                finally 
                {
                    //計(jì)數(shù)器減一
                    countDownLatch.countDown();
                }
            });
        }
        countDownLatch.await();
        logger.info("所有的子線程執(zhí)行完成,主線程"+Thread.currentThread().getName()+"開(kāi)始執(zhí)行");
    }

    private static void invokeServiec() throws InterruptedException
    {
        logger.info(Thread.currentThread().getName()+",開(kāi)始執(zhí)行任務(wù)");
        Thread.sleep(300);
    }
}

說(shuō)明:CountDownLatch中有兩個(gè)方法一個(gè)是await()方法,調(diào)用這個(gè)方法的線程會(huì)被阻塞,另外一個(gè)是countDown() 方法,調(diào)用此方法會(huì)使計(jì)數(shù)器減一,當(dāng)計(jì)數(shù)器的值為0時(shí),調(diào)用await()方法被阻塞的線程才會(huì)被喚醒。

執(zhí)行結(jié)果:

原理說(shuō)明

CountDownLatch 是一個(gè)計(jì)數(shù)器閉鎖,通過(guò)它可以完成類似于阻塞當(dāng)前線程的功能,即:一個(gè)線程或多個(gè)線程一直等待,直到其他線程執(zhí)行的操作完成。

基本原理

CountDownLatch

CountDownLatch內(nèi)部定義計(jì)數(shù)器和一個(gè)隊(duì)列。當(dāng)計(jì)數(shù)器的值遞減為0之前,阻塞隊(duì)列里面的線程處于掛起狀態(tài),當(dāng)計(jì)數(shù)器遞減到0時(shí)會(huì)喚醒阻塞隊(duì)列所有線程,計(jì)數(shù)器是一個(gè)標(biāo)志,可以表示一個(gè)任務(wù)一個(gè)線程,也可以表示一個(gè)倒計(jì)時(shí)器。

常用的方法

countDown:用于使計(jì)數(shù)器減一,其一般是執(zhí)行任務(wù)的線程調(diào)用. await: 使用線程處于等待狀態(tài),其一般是主線程調(diào)用.

countDown

countDown實(shí)現(xiàn)方法如下:

說(shuō)明:sync是一個(gè)AQS的隊(duì)列,調(diào)用的為AQS的releaseShared方法,其具體實(shí)現(xiàn)如下:

而releaseShared調(diào)用為CountDownLatch中的內(nèi)部類sync中的tryReleaseShared方法,具體實(shí)現(xiàn)如下:

tryReleaseShared(int)方法即對(duì)state屬性進(jìn)行減一操作的代碼.通過(guò)CAS進(jìn)行減操作來(lái)保證原子性,其會(huì)比較state是否為c,如果是則將其設(shè)置為nextc(自減1),如果state不為c,則說(shuō)明有另外的線程在getState()方法和compareAndSetState()方法調(diào)用之間對(duì)state進(jìn)行了設(shè)置,當(dāng)前線程也就沒(méi)有成功設(shè)置state屬性的值,其會(huì)進(jìn)入下一次循環(huán)中,如此往復(fù),直至其成功設(shè)置state屬性的值,即countDown()方法調(diào)用成功。

而doReleaseShared方法調(diào)用的為AbstractQueuedSynchronizer簡(jiǎn)稱AQS的doReleaseShared方法,

說(shuō)明:首先判斷頭結(jié)點(diǎn)不為空,且不為尾節(jié)點(diǎn),說(shuō)明等待隊(duì)列中有等待喚醒的線程,這里需要說(shuō)明的是,在等待隊(duì)列中,頭節(jié)點(diǎn)中并沒(méi)有保存正在等待的線程,其只是一個(gè)空的Node對(duì)象,真正等待的線程是從頭節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)開(kāi)始存放的,因而會(huì)有對(duì)頭結(jié)點(diǎn)是否等于尾節(jié)點(diǎn)的判斷。在判斷等待隊(duì)列中有正在等待的線程之后,其會(huì)清除頭結(jié)點(diǎn)的狀態(tài)信息,并且調(diào)用unparkSuccessor(Node)方法喚醒頭結(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn),使其繼續(xù)往下執(zhí)行。如下是unparkSuccessor(Node)方法的具體實(shí)現(xiàn):

可以看到,unparkSuccessor(Node)方法的作用是喚醒離傳入節(jié)點(diǎn)最近的一個(gè)處于等待狀態(tài)的線程,使其繼續(xù)往下執(zhí)行。

await

await方法實(shí)現(xiàn)如下:

await()方法調(diào)用了Sync對(duì)象的方法acquireSharedInterruptibly(int)方法,該方法的具體實(shí)現(xiàn)如下:

g

在doAcquireSharedInterruptibly(int)方法中,首先使用當(dāng)前線程創(chuàng)建一個(gè)共享模式的節(jié)點(diǎn)。然后在一個(gè)for循環(huán)中判斷當(dāng)前線程是否獲取到執(zhí)行權(quán)限,如果有(r >= 0判斷)則將當(dāng)前節(jié)點(diǎn)設(shè)置為頭節(jié)點(diǎn),并且喚醒后續(xù)處于共享模式的節(jié)點(diǎn);如果沒(méi)有,則對(duì)調(diào)用shouldParkAfterFailedAcquire(Node, Node)和parkAndCheckInterrupt()方法使當(dāng)前線程處于"擱置"狀態(tài),該"擱置"狀態(tài)是由操作系統(tǒng)進(jìn)行的,這樣可以避免該線程無(wú)限循環(huán)而獲取不到執(zhí)行權(quán)限,造成資源浪費(fèi),這里也就是線程處于等待狀態(tài)的位置,也就是說(shuō)當(dāng)線程被阻塞的時(shí)候就是阻塞在這個(gè)位置。當(dāng)有多個(gè)線程調(diào)用await()方法而進(jìn)入等待狀態(tài)時(shí),這幾個(gè)線程都將等待在此處。

總結(jié)

本文對(duì)JUC的工具類CountDownLatch進(jìn)行詳細(xì)的講解,如有疑問(wèn)請(qǐng)隨時(shí)反饋。

到此這篇關(guān)于JUC系列學(xué)習(xí)工具類CountDownLatch詳解的文章就介紹到這了,更多相關(guān)JUC工具類CountDownLatch 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Linux系統(tǒng)下更換jdk版本詳細(xì)步驟

    Linux系統(tǒng)下更換jdk版本詳細(xì)步驟

    隨著Java語(yǔ)言的不斷更新,多個(gè)版本的JDK在現(xiàn)在的Linux環(huán)境中都存在,使得不同的開(kāi)發(fā)人員可以按照自己的需求使用不同的JDK版本,這篇文章主要給大家介紹了關(guān)于Linux系統(tǒng)下更換jdk版本的詳細(xì)步驟,需要的朋友可以參考下
    2023-12-12
  • SpringBoot雪花算法主鍵ID傳到前端后精度丟失問(wèn)題的解決

    SpringBoot雪花算法主鍵ID傳到前端后精度丟失問(wèn)題的解決

    本文主要介紹了SpringBoot雪花算法主鍵ID傳到前端后精度丟失問(wèn)題的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • SpringBoot框架實(shí)現(xiàn)切換啟動(dòng)開(kāi)發(fā)環(huán)境和測(cè)試環(huán)境

    SpringBoot框架實(shí)現(xiàn)切換啟動(dòng)開(kāi)發(fā)環(huán)境和測(cè)試環(huán)境

    這篇文章主要介紹了SpringBoot框架實(shí)現(xiàn)切換啟動(dòng)開(kāi)發(fā)環(huán)境和測(cè)試環(huán)境,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java鎖的升級(jí)策略 偏向鎖 輕量級(jí)鎖 重量級(jí)鎖

    Java鎖的升級(jí)策略 偏向鎖 輕量級(jí)鎖 重量級(jí)鎖

    在本文中小編給的大家整理了關(guān)于Java鎖的升級(jí)策略 偏向鎖 輕量級(jí)鎖 重量級(jí)鎖的相關(guān)知識(shí)點(diǎn)內(nèi)容,需要的朋友們參考下。
    2019-06-06
  • spring boot 防止重復(fù)提交實(shí)現(xiàn)方法詳解

    spring boot 防止重復(fù)提交實(shí)現(xiàn)方法詳解

    這篇文章主要介紹了spring boot 防止重復(fù)提交實(shí)現(xiàn)方法,結(jié)合實(shí)例形式詳細(xì)分析了spring boot 防止重復(fù)提交具體配置、實(shí)現(xiàn)方法及操作注意事項(xiàng),需要的朋友可以參考下
    2019-11-11
  • springboot3請(qǐng)求參數(shù)種類及接口測(cè)試案例小結(jié)

    springboot3請(qǐng)求參數(shù)種類及接口測(cè)試案例小結(jié)

    這篇文章主要介紹了springboot3請(qǐng)求參數(shù)種類及接口測(cè)試案例小結(jié),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-10-10
  • 攔截JSP頁(yè)面,校驗(yàn)是否已登錄詳解及實(shí)現(xiàn)代碼

    攔截JSP頁(yè)面,校驗(yàn)是否已登錄詳解及實(shí)現(xiàn)代碼

    這篇文章主要介紹了攔截JSP頁(yè)面,校驗(yàn)是否已登錄詳解及實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • Java的springcloud Sentinel是什么你知道嗎

    Java的springcloud Sentinel是什么你知道嗎

    這篇文章主要介紹了Java之springcloud Sentinel案例講解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Java中Elasticsearch的核心概念詳解

    Java中Elasticsearch的核心概念詳解

    這篇文章主要介紹了Java中Elasticsearch的核心概念詳解,Elasticsearch 是一個(gè)分布式、免費(fèi)和開(kāi)放的搜索和分析引擎,適用于所有類型的數(shù)據(jù),包括文本、數(shù)字、地理空間、結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù),需要的朋友可以參考下
    2023-07-07
  • java判斷對(duì)象中某個(gè)屬性是否為空方法代碼

    java判斷對(duì)象中某個(gè)屬性是否為空方法代碼

    這篇文章主要給大家介紹了關(guān)于java判斷對(duì)象中某個(gè)屬性是否為空的相關(guān)資料,最近遇到后臺(tái)接收值的時(shí)候,需要對(duì)接收對(duì)象進(jìn)行非空校驗(yàn),需要的朋友可以參考下
    2023-07-07

最新評(píng)論