欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java并發(fā)編程中的CyclicBarrier線程屏障詳解

 更新時間:2023年12月27日 08:52:35   作者:緣來如此09  
這篇文章主要介紹了Java并發(fā)編程中的CyclicBarrier線程屏障詳解,

一、簡介

CyclicBarrier的字面意思是可循環(huán)使用(Cyclic)的屏障(Barrier)。它要做的事情是,讓一組線程到達一個屏障(也可以叫同步點)時被阻塞,直到最后一個線程到達屏障時,屏障才會開門,所有被屏障攔截的線程才會繼續(xù)運行。下圖演示了這一過程。

二、與countdownlatch的區(qū)別

它的主要作用其實和CountDownLanch差不多,都是讓一組線程到達一個屏障時被阻塞,直到最后一個線程到達屏障時,屏障會被打開,所有被屏障阻塞的線程才會繼續(xù)執(zhí)行,不過它是可以循環(huán)執(zhí)行的,這是它與CountDownLanch最大的不同。

cyclicbarrier-2

三、核心參數(shù)

 /** The lock for guarding barrier entry */
    // 可重入鎖
    private final ReentrantLock lock = new ReentrantLock();
    /** Condition to wait on until tripped */
    // 條件隊列,具體看AQS
    private final Condition trip = lock.newCondition();
    /** The number of parties */
    // 參與的線程數(shù)量
    private final int parties;
    /* The command to run when tripped */
    // 由最后一個進入 barrier 的線程執(zhí)行的操作
    private final Runnable barrierCommand;
    /** The current generation */
    // 當前代
    private Generation generation = new Generation();
    // 正在等待進入屏障的線程數(shù)量
    private int count;

四、構造方法

public CyclicBarrier(int parties, Runnable barrierAction) {
        // 參與的線程數(shù)量小于等于0,拋出異常
        if (parties <= 0) throw new IllegalArgumentException();
        // 設置parties
        this.parties = parties;
        // 設置count
        this.count = parties;
        // 設置barrierCommand
        this.barrierCommand = barrierAction;
    }

該構造函數(shù)可以指定關聯(lián)該CyclicBarrier的線程數(shù)量,并且可以指定在所有線程都進入屏障后的執(zhí)行動作,該執(zhí)行動作由最后一個進行屏障的線程執(zhí)行。

五、核心方法

await方法

(1)dowait方法

await中調用dowait
private int dowait(boolean timed, long nanos)
        throws InterruptedException, BrokenBarrierException,
               TimeoutException {
        // 保存當前鎖
        final ReentrantLock lock = this.lock;
        // 鎖定
        lock.lock();
        try {
            // 保存當前代
            final Generation g = generation;
            if (g.broken) // 屏障被破壞,拋出異常
                throw new BrokenBarrierException();
            if (Thread.interrupted()) { // 線程被中斷
                // 損壞當前屏障,并且喚醒所有的線程,只有擁有鎖的時候才會調用
                breakBarrier();
                // 拋出異常
                throw new InterruptedException();
            }
            // 減少正在等待進入屏障的線程數(shù)量
            int index = --count;
            if (index == 0) {  // 正在等待進入屏障的線程數(shù)量為0,所有線程都已經進入
                // 運行的動作標識
                boolean ranAction = false;
                try {
                    // 保存運行動作
                    final Runnable command = barrierCommand;
                    if (command != null) // 動作不為空
                        // 運行
                        command.run();
                    // 設置ranAction狀態(tài)
                    ranAction = true;
                    // 進入下一代
                    nextGeneration();
                    return 0;
                } finally {
                    if (!ranAction) // 沒有運行的動作
                        // 損壞當前屏障
                        breakBarrier();
                }
            }
            // loop until tripped, broken, interrupted, or timed out
            // 無限循環(huán)
            for (;;) {
                try {
                    if (!timed) // 沒有設置等待時間
                        // 等待
                        trip.await(); 
                    else if (nanos > 0L) // 設置了等待時間,并且等待時間大于0
                        // 等待指定時長
                        nanos = trip.awaitNanos(nanos);
                } catch (InterruptedException ie) { 
                    if (g == generation && ! g.broken) { // 等于當前代并且屏障沒有被損壞
                        // 損壞當前屏障
                        breakBarrier();
                        // 拋出異常
                        throw ie;
                    } else { // 不等于當前帶后者是屏障被損壞
                        // We're about to finish waiting even if we had not
                        // been interrupted, so this interrupt is deemed to
                        // "belong" to subsequent execution.
                        // 中斷當前線程
                        Thread.currentThread().interrupt();
                    }
                }
                if (g.broken) // 屏障被損壞,拋出異常
                    throw new BrokenBarrierException();
                if (g != generation) // 不等于當前代
                    // 返回索引
                    return index;
                if (timed && nanos <= 0L) { // 設置了等待時間,并且等待時間小于0
                    // 損壞屏障
                    breakBarrier();
                    // 拋出異常
                    throw new TimeoutException();
                }
            }
        } finally {
            // 釋放鎖
            lock.unlock();
        }
    }

(2)核心流程

(3)nextGeneration方法

該方法會喚醒所有線程并且重置次數(shù),這也是為什么CyclicBarrier可以循環(huán)調用的原因

private void nextGeneration() {
        // signal completion of last generation
        // 喚醒所有線程
        trip.signalAll();
        // set up next generation
        // 恢復正在等待進入屏障的線程數(shù)量
        count = parties;
        // 新生一代
        generation = new Generation();
    }

六、應用

 
    static class MyThread extends Thread {
        private CyclicBarrier cb;
        public MyThread(String name, CyclicBarrier cb) {
            super(name);
            this.cb = cb;
        }
        public void run() {
            System.out.println(Thread.currentThread().getName() + " going to await");
            try {
                cb.await();
                System.out.println(Thread.currentThread().getName() + " continue");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
        CyclicBarrier cb = new CyclicBarrier(3, new Thread("barrierAction") {
            public void run() {
                System.out.println(Thread.currentThread().getName() + " barrier action");
            }
        });
        MyThread t1 = new MyThread("t1", cb);
        MyThread t2 = new MyThread("t2", cb);
        t1.start();
        t2.start();
        System.out.println(Thread.currentThread().getName() + " going to await");
        cb.await();
        System.out.println(Thread.currentThread().getName() + " continue");
    }

運行結果:

所以調用時序為:

到此這篇關于Java并發(fā)編程中的CyclicBarrier線程屏障詳解的文章就介紹到這了,更多相關CyclicBarrier線程屏障內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • SpringBoot開發(fā)案例之配置Druid數(shù)據庫連接池的示例

    SpringBoot開發(fā)案例之配置Druid數(shù)據庫連接池的示例

    本篇文章主要介紹了SpringBoot開發(fā)案例之配置Druid數(shù)據庫連接池的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • MyBatis查詢時屬性名和字段名不一致問題的解決方法

    MyBatis查詢時屬性名和字段名不一致問題的解決方法

    這篇文章主要給大家介紹了關于MyBatis查詢時屬性名和字段名不一致問題的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • Java遞歸實現(xiàn)評論多級回復功能

    Java遞歸實現(xiàn)評論多級回復功能

    這篇文章主要介紹了Java遞歸實現(xiàn)評論多級回復功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • Java中的static關鍵字用法總結

    Java中的static關鍵字用法總結

    這篇文章主要介紹了Java中的static關鍵字用法總結,static是Java50個關鍵字之一,static關鍵字可以用來修飾代碼塊表示靜態(tài)代碼塊,修飾成員變量表示全局靜態(tài)成員變量,修飾方法表示靜態(tài)方法,需要的朋友可以參考下
    2023-11-11
  • java 代碼中預防空指針異常的處理辦法

    java 代碼中預防空指針異常的處理辦法

    個人在做項目時,對NullPointerException的幾點總結,請網友拍磚!??!多多提意見,
    2013-03-03
  • Java中使用阻塞隊列控制線程集實例

    Java中使用阻塞隊列控制線程集實例

    這篇文章主要介紹了Java控制阻塞隊列線程集實例,本文用一個程序展示了如何使用阻塞隊列來控制線程集,程序功能是在一個目錄及它的所有子目錄下搜索所有文件,打印出包含指定關鍵字的文件列表,需要的朋友可以參考下
    2015-01-01
  • mybatis 加載配置文件的方法(兩種方式)

    mybatis 加載配置文件的方法(兩種方式)

    這篇文章主要介紹了mybatis 加載配置文件的方法,通過實例代碼給大家介紹了mybatis 加載配置文件的兩種方式,需要的朋友可以參考下
    2017-12-12
  • 詳解spring項目中如何動態(tài)刷新bean

    詳解spring項目中如何動態(tài)刷新bean

    這篇文章主要為大家介紹了詳解spring項目中如何動態(tài)刷新bean,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • Java并發(fā)系列之Semaphore源碼分析

    Java并發(fā)系列之Semaphore源碼分析

    這篇文章主要為大家詳細介紹了Java并發(fā)系列之Semaphore源碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • Java多線程并發(fā)編程(互斥鎖Reentrant Lock)

    Java多線程并發(fā)編程(互斥鎖Reentrant Lock)

    這篇文章主要介紹了ReentrantLock 互斥鎖,在同一時間只能被一個線程所占有,在被持有后并未釋放之前,其他線程若想獲得該鎖只能等待或放棄,需要的朋友可以參考下
    2017-05-05

最新評論