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

Java中CyclicBarrier的理解與應(yīng)用詳解

 更新時(shí)間:2023年12月22日 09:53:16   作者:正經(jīng)人z.  
這篇文章主要介紹了Java中CyclicBarrier的理解與應(yīng)用詳解,CyclicBarrier類是JUC框架中的工具類,也是一個(gè)同步輔助裝置:允許多個(gè)線程去等待直到全部線程抵達(dá)了公共的柵欄點(diǎn),需要的朋友可以參考下

一、概述

CyclicBarrier類是JUC框架中的工具類,也是一個(gè)同步輔助裝置:允許多個(gè)線程去等待直到全部線程抵達(dá)了公共的柵欄點(diǎn)。

它的一個(gè)很明顯的特點(diǎn)就是Cyclic 循環(huán),也就是說柵欄是可以循環(huán)使用的,激活循環(huán)使用的條件是當(dāng)所有線程通過了柵欄并釋放。

二、源碼分析

//靜態(tài)內(nèi)部類,用于表示屏障的狀態(tài)
private static class Generation {
        boolean broken = false;
    }
//重入鎖,用于并發(fā)場景下的加鎖和釋放鎖
    private final ReentrantLock lock = new ReentrantLock();
//通過重入鎖拿到條件對象,調(diào)用await方法會進(jìn)入到條件隊(duì)列中
    private final Condition trip = lock.newCondition();
//表示線程數(shù),可以立即為這些線程數(shù)都執(zhí)行完后,屏障才會打破進(jìn)入下一代
    private final int parties;
//這個(gè)是屏障被打破后,執(zhí)行的一個(gè)任務(wù)
    private final Runnable barrierCommand;
//內(nèi)部內(nèi)實(shí)例,存儲屏障狀態(tài)
    private Generation generation = new Generation();
  //等待執(zhí)行的線程數(shù)
    private int count;
    //進(jìn)入下一代,其實(shí)就是下一個(gè)新的循環(huán),觸發(fā)條件是所有的線程都執(zhí)行完,屏障被打破時(shí)
    private void nextGeneration() {
        // signal completion of last generation
        trip.signalAll();
        // set up next generation
        count = parties;
        generation = new Generation();
    }
//打破屏障,喚醒條件隊(duì)列中線程
private void breakBarrier() {
        generation.broken = true;
        count = parties;
        trip.signalAll();
    }
====================================================  核心方法   =================================================================
private int dowait(boolean timed, long nanos)
        throws InterruptedException, BrokenBarrierException,
               TimeoutException {
        final ReentrantLock lock = this.lock;
        //上鎖
        lock.lock();
        try {
            final Generation g = generation;
            //判斷屏障的狀態(tài)
            if (g.broken)
                throw new BrokenBarrierException();
           //判斷線程是否被打斷
            if (Thread.interrupted()) {
                breakBarrier();
                throw new InterruptedException();
            }
			//被執(zhí)行的線程數(shù)減一
            int index = --count;
            //如果當(dāng)前的線程都執(zhí)行完畢
            if (index == 0) {  // tripped
                boolean ranAction = false;
                try {
                    final Runnable command = barrierCommand;
                    if (command != null)
                    //執(zhí)行墊底的barrierCommand方法
                        command.run();
                    ranAction = true;
                    //開始下一個(gè)循環(huán),其實(shí)也就是重置一下屏障的狀態(tài),將parties的值重新復(fù)制給count并喚醒在條件隊(duì)列中的線程
                    nextGeneration();
                    return 0;
                } finally {
                    if (!ranAction)
                    //打破屏障
                        breakBarrier();
                }
            }
			//無限循環(huán)
            for (;;) {
                try {
                    if (!timed)
                    //調(diào)用await方法等待,其實(shí)就是到了條件隊(duì)列condition中去了,等待被喚醒
                        trip.await();
                    else if (nanos > 0L)
                        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) {
                    breakBarrier();
                    throw new TimeoutException();
                }
            }
        } finally {
            lock.unlock();
        }
    }
===================================================================================================================================
//構(gòu)造函數(shù),傳入線程數(shù)和執(zhí)行的方法
public CyclicBarrier(int parties, Runnable barrierAction) {
        if (parties <= 0) throw new IllegalArgumentException();
        this.parties = parties;
        this.count = parties;
        this.barrierCommand = barrierAction;
    }
public CyclicBarrier(int parties) {
        this(parties, null);
    }
public int await() throws InterruptedException, BrokenBarrierException {
        try {
            return dowait(false, 0L);
        } catch (TimeoutException toe) {
            throw new Error(toe); // cannot happen
        }
    }
//重置count,其實(shí)就是開啟一個(gè)新的循環(huán)
public void reset() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            breakBarrier();   // break the current generation
            nextGeneration(); // start a new generation
        } finally {
            lock.unlock();
        }
    }

三、練習(xí)

public class MyThread extends Thread{
    private String name;
    private CyclicBarrier cb;
    public MyThread(String name,CyclicBarrier cb){
        this.name = name;
        this.cb = cb;
    }
    @Override
    public void run() {
        try{
            System.out.println(Thread.currentThread().getName()+"開始執(zhí)行");
            cb.await();
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            System.out.println(Thread.currentThread().getName()+"繼續(xù)");
        }
    }
}
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
        CyclicBarrier cb = new CyclicBarrier(3, new Runnable() {
            @Override
            public void run() {
                System.out.println("屏障被打破,重新開始==========");
            }
        });
        MyThread t1 = new MyThread("t1",cb);
        MyThread t2 = new MyThread("t2",cb);
        t1.start();
        t2.start();
        cb.await();
    }

四、總結(jié)

1、CyclicBarrier和CountDownLatch極為類似,兩者都是柵欄工具類,不同的是,CyclicBarrier可以循環(huán)使用柵欄,而CountDownLatch只能使用一次。兩者都是減法計(jì)數(shù),但是數(shù)值的存儲屬性卻不相同,CyclicBarrier使用的是自己的私有屬性parties,而CountDownLatch使用的是AQS類的state屬性。

2、CyclicBarrier和CountDownLatch還有一個(gè)不同點(diǎn)在于:CyclicBarrier在所有線程執(zhí)行完后,屏障被打破時(shí),會執(zhí)行barrierCommand最終任務(wù),當(dāng)然不是必須的。

3、在何時(shí)使用CountDownLatch和CountDownLatch,還是有稍微差異:CyclicBarrier適合那種跨欄比賽,但是要求所有參賽選手跨過同一個(gè)欄后才能跨下一個(gè)欄。CountDownLatch適合那種游戲,選手都準(zhǔn)備好了,才能開始游戲主線程。 其實(shí)說來說去,無非就是CountDownLatch適合循環(huán)的場景,CountDownLatch適合一次性的場景!

到此這篇關(guān)于Java中CyclicBarrier的理解與應(yīng)用詳解的文章就介紹到這了,更多相關(guān)CyclicBarrier的理解與應(yīng)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何判斷java是32位的還是64位的

    如何判斷java是32位的還是64位的

    這篇文章主要介紹了如何判斷java是32位的還是64位的問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • SpringBoot集成IJPay實(shí)現(xiàn)微信v3支付的示例代碼

    SpringBoot集成IJPay實(shí)現(xiàn)微信v3支付的示例代碼

    本文主要介紹了SpringBoot集成IJPay實(shí)現(xiàn)微信v3支付的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • java ThreadLocal使用案例詳解

    java ThreadLocal使用案例詳解

    這篇文章主要為大家詳細(xì)介紹了java ThreadLocal的使用案例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • 新版idea創(chuàng)建spring boot項(xiàng)目的詳細(xì)教程

    新版idea創(chuàng)建spring boot項(xiàng)目的詳細(xì)教程

    這篇文章給大家介紹了新版idea創(chuàng)建spring boot項(xiàng)目的詳細(xì)教程,本教程對新手小白友好,若根據(jù)教程創(chuàng)建出現(xiàn)問題導(dǎo)致失敗可下載我提供的源碼,在文章最后,本教程較新,文中通過圖文給大家介紹的非常詳細(xì),感興趣的朋友可以參考下
    2024-01-01
  • java小知識之查詢數(shù)據(jù)庫數(shù)據(jù)的元信息

    java小知識之查詢數(shù)據(jù)庫數(shù)據(jù)的元信息

    這篇文章主要給大家介紹了關(guān)于java小知識之查詢數(shù)據(jù)庫數(shù)據(jù)的元信息,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2021-10-10
  • btrace定位生產(chǎn)故障的方法示例

    btrace定位生產(chǎn)故障的方法示例

    這篇文章主要介紹了btrace定位生產(chǎn)故障的方法示例,文中通過示例代碼介紹的很詳細(xì),相信對大家具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。
    2017-02-02
  • Springboot讀取外部配置文件,項(xiàng)目部署時(shí)配置讀取不到問題及解決

    Springboot讀取外部配置文件,項(xiàng)目部署時(shí)配置讀取不到問題及解決

    這篇文章主要介紹了Springboot讀取外部配置文件,項(xiàng)目部署時(shí)配置讀取不到問題及解決,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • 淺談Spring Cloud中的API網(wǎng)關(guān)服務(wù)Zuul

    淺談Spring Cloud中的API網(wǎng)關(guān)服務(wù)Zuul

    這篇文章主要介紹了淺談Spring Cloud中的API網(wǎng)關(guān)服務(wù)Zuul,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • Java 如何從spring容器中獲取注入的bean對象

    Java 如何從spring容器中獲取注入的bean對象

    這篇文章主要介紹了Java 如何從spring容器中獲取注入的bean對象,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-11-11
  • 淺談Java高并發(fā)解決方案以及高負(fù)載優(yōu)化方法

    淺談Java高并發(fā)解決方案以及高負(fù)載優(yōu)化方法

    這篇文章主要介紹了淺談Java高并發(fā)解決方案以及高負(fù)載優(yōu)化方法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評論