第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

首頁 慕課教程 Java并發(fā)工具 Java并發(fā)工具 同步計(jì)數(shù)器 CountDownLatch

同步計(jì)數(shù)器 CountDownLatch

1. 前言

本節(jié)帶領(lǐng)大家認(rèn)識(shí)第二個(gè)常用的 Java 并發(fā)工具類之 CountDownLatch。

本節(jié)先介紹 CountDownLatch 工具類表達(dá)的概念和最基本用法,接著通過一個(gè)生活中的例子為大家解釋 CountDownLatch 工具類的使用場(chǎng)合,然后通過簡(jiǎn)單的編碼實(shí)現(xiàn)此場(chǎng)景,最后帶領(lǐng)大家熟悉 CountDownLatch 工具類的其他重要方法。

下面我們正式開始介紹吧。

2. 概念解釋

CountDownLatch 工具類從字面理解為 “倒計(jì)數(shù)鎖”,其內(nèi)部使用一個(gè)計(jì)數(shù)器進(jìn)行實(shí)現(xiàn),計(jì)數(shù)器初始值為線程的數(shù)量。當(dāng)每一個(gè)線程完成自己的任務(wù)后,計(jì)數(shù)器的值就會(huì)減一。當(dāng)計(jì)數(shù)器的值為 0 時(shí),表示所有的線程都已經(jīng)完成了任務(wù),然后在 CountDownLatch 上等待的線程就可以恢復(fù)繼續(xù)執(zhí)行后繼任務(wù)。是不是很抽象,其實(shí)很簡(jiǎn)單,看下面的圖例。
圖片描述
這就是 CountDownLatch 工具類的基本邏輯。概念已經(jīng)了解了,CountDownLatch 工具類最基本的用法是怎樣的呢?看下面。

3. 基本用法

// 創(chuàng)建一個(gè) CountDownLatch 對(duì)象
CountDownLatch countDownLatch = new CountDownLatch(子線程個(gè)數(shù));

// 子線程1開始處理邏輯
...
// 子線程執(zhí)行完所有邏輯進(jìn)行計(jì)數(shù)器減1
countDownLatch.countDown();

// 子線程n開始處理邏輯
...
// 子線程執(zhí)行完所有邏輯進(jìn)行計(jì)數(shù)器減1
countDownLatch.countDown();

// 主線程等待所有子線程執(zhí)行完
countDownLatch.await();
// 主線程繼續(xù)執(zhí)行后繼邏輯
...

是不是很簡(jiǎn)單,CountDownLatch 應(yīng)用在哪些場(chǎng)合比較合適呢?下面我們給出最常用的場(chǎng)景說明。

4. 常用場(chǎng)景

CountDownLatch 經(jīng)常用于某一線程在開始運(yùn)行前等待其他關(guān)聯(lián)線程執(zhí)行完畢的場(chǎng)合。

比如我們制作一張復(fù)雜報(bào)表,報(bào)表的各部分可以安排對(duì)應(yīng)的一個(gè)線程進(jìn)行計(jì)算,只有當(dāng)所有線程都執(zhí)行完畢后,再由最終的報(bào)表輸出線程進(jìn)行報(bào)表文件生成。

下面我們使用 CountDownLatch 實(shí)現(xiàn)這個(gè)例子。假設(shè)這張報(bào)表有 5 個(gè)部分,我們總共安排 5 個(gè)子線程分別計(jì)算,再設(shè)置 1 個(gè)報(bào)表輸出線程用于最終生成報(bào)表文件。請(qǐng)看下面代碼。

5. 場(chǎng)景案例

import java.util.Random;
import java.util.concurrent.CountDownLatch;

public class CountDownLatchTest {
    // 創(chuàng)建一個(gè) CountDownLatch 對(duì)象,初始化為 5, 代表需要控制同步的子線程個(gè)數(shù)
    static int threadCount = 5;
    private static CountDownLatch countDownLatch = new CountDownLatch(threadCount);
    // 報(bào)表生成主線程
    public static void main(String[] args) throws InterruptedException {
        // 定義報(bào)表子線程
        for(int i=1; i<=threadCount; i++) {
            // 開始報(bào)表子線程處理
            new Thread(new Runnable() {
                public void run() {
                    // 模擬報(bào)表數(shù)據(jù)計(jì)算時(shí)間
                    try {
                        Thread.sleep(new Random().nextInt(5000));
                    } catch (Exception e) {}
                    System.out.println( Thread.currentThread().getName() + "已經(jīng)處理完畢");
                    countDownLatch.countDown();
                }
            }, "報(bào)表子線程" + i).start();
        }
        // 主線程等待所有子線程運(yùn)行完畢后輸出報(bào)表文件
        countDownLatch.await();
        System.out.println("報(bào)表數(shù)據(jù)已經(jīng)全部計(jì)算完畢,開始生成報(bào)表文件...");
    }
}

運(yùn)行上面代碼,我們觀察一下運(yùn)行結(jié)果。

報(bào)表子線程3已經(jīng)處理完畢
報(bào)表子線程5已經(jīng)處理完畢
報(bào)表子線程1已經(jīng)處理完畢
報(bào)表子線程4已經(jīng)處理完畢
報(bào)表子線程2已經(jīng)處理完畢
報(bào)表數(shù)據(jù)已經(jīng)全部計(jì)算完畢,開始生成報(bào)表文件...

觀察結(jié)果,和我們的預(yù)期一致。注意體會(huì) CountDownLatch 提供的多線程共同協(xié)作的模型。

6. 其他方法介紹

除過上面代碼中使用的最基本的 countDown ()、await () 方法之外,還有兩個(gè)方法大家可以了解一下。

  1. await (long, TimeUnit) 方法
    此方法提供了更靈活的等待參數(shù),可以設(shè)置等待超時(shí)時(shí)間。當(dāng)?shù)却^了設(shè)定的時(shí)限,則不再阻塞直接開始后繼處理。

  2. getCount () 方法
    調(diào)用此方法,可獲得當(dāng)前計(jì)數(shù)器的數(shù)值,了解整體處理進(jìn)度。

7. 小結(jié)

本節(jié)解釋了 CountDownLatch 的基本邏輯模型,且通過一個(gè)簡(jiǎn)單的例子,介紹了 CountDownLatch 的使用場(chǎng)景和基本用法。希望大家在學(xué)習(xí)過程中,多思考勤練習(xí),早日掌握之。