成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Java多線程同步工具箱之CountDownLatch篇

lufficc / 892人閱讀

摘要:多線程同步工具箱之篇前言的多線程協(xié)調(diào)工具,,,都是在多線程代碼中使用比較多的工具類(lèi)之一。毫不夸張的說(shuō),這幾個(gè)類(lèi),是等同于解決多線程問(wèn)的包,實(shí)在有必要添加到程序員的工具箱里面。

Java多線程同步工具箱之CountDownLatch篇 前言

Java的多線程協(xié)調(diào)工具CountDownLatch,Semaphore,CyclicBarrier,ReadWriteLock都是在多線程代碼中使用比較多的工具類(lèi)之一。掌握及理解這幾個(gè)類(lèi)的實(shí)現(xiàn),對(duì)解決和理解多線程中復(fù)雜的業(yè)務(wù)狀況有很重要的作用。毫不夸張的說(shuō),這幾個(gè)類(lèi),是等同于解決多線程問(wèn)的java.util包,實(shí)在有必要添加到程序員的工具箱里面。

此次文章,將分幾篇總結(jié)及解讀一下這些工具類(lèi)的具體用法和范例,最后,希望可以再深入一點(diǎn)去理解這幾個(gè)多線程工具的實(shí)現(xiàn)。

1. CountDownLatch(倒數(shù)鎖)

CountDownLatch是一個(gè)常用的多線程協(xié)調(diào)工具:主要為協(xié)調(diào)一個(gè)或多個(gè)線程完成后,主線程進(jìn)行某個(gè)操作的功能。

Latch原指門(mén)閂,CountDownLatch譯為倒數(shù)鎖倒是不太過(guò)分??梢岳斫鉃椋菏褂弥骶€程初始化一個(gè)有N個(gè)子鎖的鎖,任務(wù)開(kāi)始的時(shí),分配給N個(gè)線程每個(gè)線程持有一把鑰匙,每個(gè)線程到某個(gè)狀態(tài)后(一般為完成),可以使用線程持有的鑰匙打開(kāi)主線程持有的鎖,直至所有N個(gè)鎖都被打開(kāi),主線程才可以繼續(xù)其他任務(wù)。

1.1 API

從API上看我們可以關(guān)注下面幾個(gè)CountDownLatch提供了幾個(gè)接口:

構(gòu)造方法CountDownLatch(int)

構(gòu)造方法十分簡(jiǎn)單,注入一個(gè)int,初始化倒數(shù)鎖的大小。

await()

等待所有鎖被解開(kāi),該函數(shù)還有一個(gè)帶等待時(shí)長(zhǎng)及等待時(shí)間單位的重寫(xiě)await(long time, TimeUnit unit),用于避免過(guò)度的等待造成的死鎖。

countDown()

解鎖方法,解開(kāi)一個(gè)鎖,知道持有的鎖數(shù)量為0,則接觸await的狀態(tài)。

getCount()

獲取當(dāng)前的剩余的鎖的數(shù)量。

1.2 范例

在范例中,我們簡(jiǎn)單的使用一個(gè)主線程,發(fā)起若干個(gè)子線程,讓子線程進(jìn)行休眠的例子作為測(cè)試倒數(shù),讓各個(gè)子線程導(dǎo)數(shù)完通知解鎖,主線程會(huì)被在所有子線程完成解鎖后通知所有任務(wù)完成。

1.2.1 使用倒數(shù)鎖前
App.java

import java.util.concurrent.CountDownLatch;
import java.util.logging.Logger;

public class App {

    static Logger log = Logger.getAnonymousLogger();

    public static void main(String[] args) {
        
        for (int index = 0; index < 10; index++) {
            new Thread(new SubThread(index, index)).start();
        }

        // 所有的線程都完成了
        log.info("all thread finished");
    }

}
SubThread.java

import java.util.concurrent.CountDownLatch;
import java.util.logging.Logger;

public class SubThread implements Runnable {

    private int id;
    private int waitSecond;

    static Logger log = Logger.getAnonymousLogger();

    public SubThread(int id, int waitSecond) {
        this.id = id;
        // 秒數(shù)*1000毫秒 = 實(shí)際等待毫秒數(shù)
        this.waitSecond = waitSecond * 1000;
    }

    public void run() {
        try {
            log.info("Thread " + id + " started.");
            // 讓Thread再飛一會(huì)兒
            Thread.sleep(waitSecond);

            log.info("Thread " + id + " end.");
            // 通知完成
        } catch (InterruptedException e) {
            log.config("error");
        }
    }

}
運(yùn)行結(jié)果

可以從結(jié)果中看到,所有的線程啟動(dòng)后,主線程就會(huì)立刻退出,子線程會(huì)在完成各自的任務(wù)后再退出。

Aug 09, 2018 6:43:22 PM online.tangbk.demo.thead.SubThread run
INFO: Thread 3 started.

...
...

Aug 09, 2018 6:43:22 PM online.tangbk.demo.thead.App main
INFO: all thread finished
Aug 09, 2018 6:43:22 PM online.tangbk.demo.thead.SubThread run
INFO: Thread 8 started.

...
...

Aug 09, 2018 6:43:31 PM online.tangbk.demo.thead.SubThread run
INFO: Thread 9 end.
1.2.2 使用倒數(shù)鎖后
App.java

import java.util.concurrent.CountDownLatch;
import java.util.logging.Logger;

public class App {

    static Logger log = Logger.getAnonymousLogger();

    public static void main(String[] args) {

        // 初始化10個(gè)線程的鎖
        CountDownLatch cdl = new CountDownLatch(10);

        for (int index = 0; index < 10; index++) {
            // 將鎖傳給子線程
            new Thread(new SubThread(index, index, cdl)).start();
        }

        try {
            // 等待所有的鎖被(倒數(shù))釋放
            cdl.await();
        } catch (InterruptedException e) {

            e.printStackTrace();
        }
        // 所有的線程都完成了
        log.info("all thread finished");
    }

}
SubThread.java

import java.util.concurrent.CountDownLatch;
import java.util.logging.Logger;

public class SubThread implements Runnable {

    private int id;
    private int waitSecond;
    private CountDownLatch cdl;

    static Logger log = Logger.getAnonymousLogger();

    public SubThread(int id, int waitSecond, CountDownLatch cdl) {
        this.id = id;
        // 秒數(shù)*1000毫秒 = 實(shí)際等待毫秒數(shù)
        this.waitSecond = waitSecond * 1000;
        this.cdl = cdl;
    }

    public void run() {
        try {
            log.info("Thread " + id + " started.");
            // 讓Thread再飛一會(huì)兒
            Thread.sleep(waitSecond);

            cdl.countDown();
            log.info("Thread " + id + " end.");
            // 通知完成
        } catch (InterruptedException e) {
            log.config("error");
        }
    }

}
運(yùn)行結(jié)果

可以從結(jié)果中看到,所有的線程啟動(dòng)后,都會(huì)等到所有線程完成等待后才結(jié)束。

Aug 09, 2018 6:29:20 PM online.tangbk.demo.thead.SubThread run
INFO: Thread 2 started.
Aug 09, 2018 6:29:20 PM online.tangbk.demo.thead.SubThread run
INFO: Thread 3 started.
Aug 09, 2018 6:29:20 PM online.tangbk.demo.thead.SubThread run
INFO: Thread 1 started.
Aug 09, 2018 6:29:20 PM online.tangbk.demo.thead.SubThread run
INFO: Thread 0 started.

...
...

Aug 09, 2018 6:29:28 PM online.tangbk.demo.thead.SubThread run
INFO: Thread 8 end.
Aug 09, 2018 6:29:29 PM online.tangbk.demo.thead.SubThread run
INFO: Thread 9 end.
Aug 09, 2018 6:29:29 PM online.tangbk.demo.thead.App main
INFO: all thread finished
1.3 CountDownLatch小結(jié)

CountDownLatch(倒數(shù)鎖)適用于需要等待子線程完成后,統(tǒng)一進(jìn)行操作的一些操作。更可以結(jié)合FutureTask的相關(guān)接口,取回子線程的結(jié)果,對(duì)結(jié)果統(tǒng)一搜集處理。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/76682.html

相關(guān)文章

  • Java線程打輔助的三個(gè)小伙子

    摘要:前言之前學(xué)多線程的時(shí)候沒(méi)有學(xué)習(xí)線程的同步工具類(lèi)輔助類(lèi)。而其它線程完成自己的操作后,調(diào)用使計(jì)數(shù)器減。信號(hào)量控制一組線程同時(shí)執(zhí)行。 前言 之前學(xué)多線程的時(shí)候沒(méi)有學(xué)習(xí)線程的同步工具類(lèi)(輔助類(lèi))。ps:當(dāng)時(shí)覺(jué)得暫時(shí)用不上,認(rèn)為是挺高深的知識(shí)點(diǎn)就沒(méi)去管了.. 在前幾天,朋友發(fā)了一篇比較好的Semaphore文章過(guò)來(lái),然后在瀏覽博客的時(shí)候又發(fā)現(xiàn)面試還會(huì)考,那還是挺重要的知識(shí)點(diǎn)。于是花了點(diǎn)時(shí)間去了解...

    pingink 評(píng)論0 收藏0
  • Java線程進(jìn)階(九)—— J.U.Clocks框架:AQS共享功能剖析(4)

    摘要:好了,繼續(xù)向下執(zhí)行,嘗試獲取鎖失敗后,會(huì)調(diào)用首先通過(guò)方法,將包裝成共享結(jié)點(diǎn),插入等待隊(duì)列,插入完成后隊(duì)列結(jié)構(gòu)如下然后會(huì)進(jìn)入自旋操作,先嘗試獲取一次鎖,顯然此時(shí)是獲取失敗的主線程還未調(diào)用,同步狀態(tài)還是。 showImg(https://segmentfault.com/img/remote/1460000016012541); 本文首發(fā)于一世流云的專(zhuān)欄:https://segmentfa...

    CompileYouth 評(píng)論0 收藏0
  • Java同步機(jī)制的底層實(shí)現(xiàn)

    摘要:在多線程編程中我們會(huì)遇到很多需要使用線程同步機(jī)制去解決的并發(fā)問(wèn)題,而這些同步機(jī)制就是多線程編程中影響正確性和運(yùn)行效率的重中之重。這五個(gè)方法之所以能指定同步器的行為,則是因?yàn)橹械钠渌椒ň褪峭ㄟ^(guò)對(duì)這五個(gè)方法的調(diào)用來(lái)實(shí)現(xiàn)的。 在多線程編程中我們會(huì)遇到很多需要使用線程同步機(jī)制去解決的并發(fā)問(wèn)題,而這些同步機(jī)制就是多線程編程中影響正確性和運(yùn)行效率的重中之重。這不禁讓我感到好奇,這些同步機(jī)制是如何...

    yintaolaowanzi 評(píng)論0 收藏0
  • 死磕 java同步系列volatile解析

    摘要:前半句是指線程內(nèi)表現(xiàn)為串行的語(yǔ)義,后半句是指指令重排序現(xiàn)象和工作內(nèi)存和主內(nèi)存同步延遲現(xiàn)象。關(guān)于內(nèi)存模型的講解請(qǐng)參考死磕同步系列之。目前國(guó)內(nèi)市面上的關(guān)于內(nèi)存屏障的講解基本不會(huì)超過(guò)這三篇文章,包括相關(guān)書(shū)籍中的介紹。問(wèn)題 (1)volatile是如何保證可見(jiàn)性的? (2)volatile是如何禁止重排序的? (3)volatile的實(shí)現(xiàn)原理? (4)volatile的缺陷? 簡(jiǎn)介 volatile...

    番茄西紅柿 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<