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

循環(huán)柵欄 CyclicBarrier

1.前言

本節(jié)帶領(lǐng)大家認識第三個常用的 Java 并發(fā)工具類之 CyclicBarrier。

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

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

2.概念解釋

所謂 Cyclic 即循環(huán)的意思,所謂 Barrier 即屏障的意思。所以綜合起來,CyclicBarrier 指的就是循環(huán)屏障,雖然這個叫法很奇怪,但是卻能很好地表達其含義。

CyclicBarrier 工具類允許一組線程相互等待,直到所有線程都到達一個公共的屏障點,然后這些線程一起繼續(xù)執(zhí)行后繼邏輯。之所以稱之為 “循環(huán)”,是因為在所有線程都釋放了對這個屏障的使用后,這個屏障還可以重新使用。我們通過一張圖可以直觀了解其表達的控制模型。
圖片描述
現(xiàn)在我們已經(jīng)了解了基本概念邏輯,CyclicBarrier 工具類最基本的用法是怎樣的呢?看下面。

3.基本用法

// 創(chuàng)建一個 CyclicBarrier 對象,初始化相互等待的線程數(shù)量
CyclicBarrier cyclicBarrier = new CyclicBarrier(線程個數(shù));

// 線程1開始處理邏輯
...
// 線程1等待其他線程執(zhí)行到屏障點
cyclicBarrier.await();
// 線程1等到了其他所有線程達到屏障點后繼續(xù)處理后繼邏輯
...

// 線程n開始處理邏輯
...
// 線程n等待其他線程執(zhí)行到屏障點
cyclicBarrier.await();
// 線程n等到了其他所有線程達到屏障點后繼續(xù)處理后繼邏輯
...

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

4.常用場景

CyclicBarrier 最適合一個由多個線程共同協(xié)作完成任務(wù)的場合。

這樣描述很抽象,我們還是舉一個生活中的例子說明:某學(xué)習(xí)班總共 5 位同學(xué),約定周末一起乘坐大巴出游,約定了共同的集合地點,雇傭了 1 位司機。請看下面代碼。

5.場景案例

import lombok.SneakyThrows;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierTest {
    // 創(chuàng)建一個 Runnable 對象,用于屏障解除時處理全局邏輯,在此例子中代表大巴司機
    private static Runnable driver = new Runnable() {
        public void run() {
            System.out.println("所有同學(xué)已經(jīng)集合完畢,開始啟動車輛出發(fā)。");
        }
    };

    // 創(chuàng)建一個 CyclicBarrier 對象,初始化為 5, 代表需要控制同步的線程個數(shù),在此例子中代表 5 位同學(xué)
    static int threadCount = 5;
    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(threadCount, driver);
    
    public static void main(String[] args) throws InterruptedException {
        // 模擬同學(xué)
        for(int i=1; i<=threadCount; i++) {
            // 模擬某個同學(xué)的動作
            new Thread(new Runnable() {
                @SneakyThrows
                public void run() {
                    System.out.println( Thread.currentThread().getName() + "已經(jīng)開始出門...");
                    // 模擬同學(xué)出門趕往集合點的用時
                    try {
                        Thread.sleep(new Random().nextInt(10000));
                    } catch (Exception e) {}
                    System.out.println( Thread.currentThread().getName() + "已經(jīng)到達集合點");
                    // 等待其他同學(xué)到達集合點(等待其他線程到達屏障點)
                    cyclicBarrier.await();
                }
            }, i + "號同學(xué)").start();
        }
    }
}

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

1號同學(xué)準(zhǔn)備出門...
2號同學(xué)準(zhǔn)備出門...
3號同學(xué)準(zhǔn)備出門...
4號同學(xué)準(zhǔn)備出門...
5號同學(xué)準(zhǔn)備出門...
5號同學(xué)已經(jīng)到達集合點
4號同學(xué)已經(jīng)到達集合點
1號同學(xué)已經(jīng)到達集合點
2號同學(xué)已經(jīng)到達集合點
3號同學(xué)已經(jīng)到達集合點
所有同學(xué)已經(jīng)集合完畢,開始啟動車輛出發(fā)。

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

6.其他方法介紹

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

  1. CyclicBarrier(int parties)
    相比案例中使用的 CyclicBarrier(int parties, Runnable barrierAction) 構(gòu)造方法,此方法只用于控制并發(fā)線程,不做屏障點到達后的其他動作。

  2. await(long timeout, TimeUnit unit) 方法
    此方法可以設(shè)置等待的時限,當(dāng)時限過后還未被喚起,則直接自行喚醒繼續(xù)執(zhí)行后繼任務(wù)。

  3. getNumberWaiting() 方法
    調(diào)用此方法,可以獲得當(dāng)前還在等待屏障點解除的線程數(shù),一般用于了解整體處理進度。

7.小結(jié)

本節(jié)通過一個簡單的例子,介紹了 CyclicBarrier 相關(guān)的概念原理,使用場景和基本用法。希望大家在學(xué)習(xí)過程中,多思考勤練習(xí),早日掌握之。