最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java的CyclicBarrier循環(huán)屏障解析

 更新時間:2023年12月16日 09:57:51   作者:niulx111  
這篇文章主要介紹了Java的CyclicBarrier循環(huán)屏障解析,CyclicBarrier和CountDownLatch一樣,是一個同步工具類,它允許一組線程相互等待直到達到某個common?barrier?point,在程序中CyclicBarrier是非常有用的,它適用于一組線程必須互相等待的情況,需要的朋友可以參考下

CyclicBarrier循環(huán)屏障

CyclicBarrier和CountDownLatch一樣,是一個同步工具類,它允許一組線程相互等待直到達到某個common barrier point。

在程序中CyclicBarrier是非常有用的,它適用于一組線程必須互相等待的情況。barrier被稱為周期是因為等待的線程在釋放后可以重用。

構(gòu)造函數(shù)

    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);
    }

CyclicBarrier有兩種構(gòu)造方法,默認(rèn)是指定一個線程數(shù)量,并把它賦給等待狀態(tài)的線程count,還有一個barrierAction任務(wù),它是在滿足barrier時,所有的線程準(zhǔn)備好之前,才執(zhí)行這個runnable,這是最后一個線程來執(zhí)行的。parties是表示必須有幾個線程要達到barrier,count是表示當(dāng)前未達到barrier的線程數(shù)量,只有count=0時,線程才能繼續(xù)執(zhí)行。

看一下它的示例。

public static void main(String[] args) {
		CyclicBarrier c = new CyclicBarrier(5,new Runnable() {
			@Override
			public void run() {
				System.out.println("開始");
			}
		});
		ExecutorService es = Executors.newCachedThreadPool();
		for (int i = 0; i < 5; i++) {
			es.execute(new Task(i, c));
		}
		es.shutdown();
	}
	static public class Task implements Runnable {
		private int i;
		private CyclicBarrier cyclicBarrier;
		public Task(int i,CyclicBarrier cyclicBarrier) {
			this.i = i;
			this.cyclicBarrier = cyclicBarrier;
		}
		@Override
		public void run() {
			System.out.println(i+"準(zhǔn)備完畢");
			try {
				cyclicBarrier.await();
				Thread.sleep(100);
				System.out.println(i+"加入了");
			} catch (InterruptedException e) {	
				e.printStackTrace();
			} catch (BrokenBarrierException e) {
				e.printStackTrace();
			}
		}
	}

執(zhí)行結(jié)果

0準(zhǔn)備完畢
4準(zhǔn)備完畢
3準(zhǔn)備完畢
1準(zhǔn)備完畢
2準(zhǔn)備完畢
開始
4加入了
1加入了
2加入了
3加入了
0加入了

看一下它的阻塞await方法。

    /**
     * 如果當(dāng)前線程不是最后一個達到的它就會休眠直到出現(xiàn)下面的任意一種情況:
     *  1. 最后一個線程達到
     *  2. 一些其他的線程中斷了當(dāng)前線程
     *  3. 一些其他的線程中斷了正在等待的線程
     *  4. 一些其他線程在等待過程中超時了
     *  5. 一些其他的線程在barrier被重置
     *  當(dāng)前線程在等待的過程中如果被中斷直接會拋出異常并且當(dāng)前線程的中斷狀態(tài)會被清除
     *  如果在等待的過程中一些線程被中斷,其他的等待線程就會拋出異常,barrier就會被設(shè)置成broken為true的狀態(tài)
     *  如果當(dāng)前線程是最后一個達到的話,如果構(gòu)造方法中有runnable任務(wù),直接由最后一個線程去執(zhí)行,其他線程繼續(xù)等待
     *  在barrier action中,如果出現(xiàn)異常會由當(dāng)前線程傳播并且barrier被設(shè)置成broken為true的狀態(tài)
     */
    public int await() throws InterruptedException, BrokenBarrierException {
        try {
            return dowait(false, 0L);
        } catch (TimeoutException toe) {
            throw new Error(toe); // 永遠不會進入catch
        }
    }

主要調(diào)用了dowait方法,看一下這個方法,方法比較長。

    /**
     * Main barrier code, covering the various policies.
     */
    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();
            }
            int index = --count;
            if (index == 0) {  // tripped
                boolean ranAction = false;
                try {
                    final Runnable command = barrierCommand;
                    if (command != null)
                        command.run();
                    ranAction = true;
                    nextGeneration();
                    return 0;
                } finally {
                    if (!ranAction)
                        breakBarrier();
                }
            }
            // loop until tripped, broken, interrupted, or timed out
            for (;;) {
                try {
                    if (!timed)
                        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();
        }
    }

首先會創(chuàng)建一個靜態(tài)內(nèi)部類Generation,這個類中只有一個屬性,broken,表示當(dāng)前屏障是否被中斷,默認(rèn)為false,未中斷.

如果當(dāng)前broken為true,就會傳播這個異常.

如果當(dāng)前線程被中斷,broken為中斷狀態(tài),調(diào)用breakBarrier方法,把broken設(shè)為true,重置count.喚醒其他的線程.

    private void breakBarrier() {
        generation.broken = true;
        count = parties;
        trip.signalAll();
    }

如果前面的條件都不成立,那就count自減,表示當(dāng)前線程已經(jīng)完成了任務(wù),當(dāng)count=0的時候,表示所有的任務(wù)都已經(jīng)完成,此時在判斷是否構(gòu)造函數(shù)中有傳入的runnable,如果command不為空,總是最后一個線程去執(zhí)行,如果在執(zhí)行這個command的過程中出現(xiàn)異常,再次調(diào)用breakBarrier方法重置count.

執(zhí)行成功,調(diào)用nextGeneration方法,喚醒所有在等待隊列上的線程,重置count.再次把broken設(shè)為false.

    private void nextGeneration() {
        // signal completion of last generation
        trip.signalAll();
        // set up next generation
        count = parties;
        generation = new Generation();
    }

如果當(dāng)前count不為0,那就進行自旋,沒有超時直接釋放鎖進入等待隊列,如果線程在釋放鎖進入等待隊列的過程中被中斷直接重置count,拋出異常.

在自旋過程中,如果發(fā)生了broken狀態(tài)的變化或者超時,直接拋出異常,并做相應(yīng)的處理,最后釋放鎖.

總結(jié)

CyclicBarrier的count是可以重用的,這是與CountDownLatch最大的區(qū)別.

barrier中任務(wù)是由最有一個線程執(zhí)行的,并且會執(zhí)行構(gòu)造方法中傳入的任務(wù).這個任務(wù)總是在到達barrier時執(zhí)行.

到此這篇關(guān)于Java的CyclicBarrier循環(huán)屏障解析的文章就介紹到這了,更多相關(guān)CyclicBarrier循環(huán)屏障內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Spring循環(huán)依賴的解決方案

    詳解Spring循環(huán)依賴的解決方案

    這篇文章主要介紹了詳解Spring循環(huán)依賴的解決方案,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • 關(guān)于MVC設(shè)計模式及流程解析

    關(guān)于MVC設(shè)計模式及流程解析

    這篇文章主要介紹了關(guān)于MVC設(shè)計模式及流程解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • SpringBoot?如何使用sharding?jdbc進行分庫分表

    SpringBoot?如何使用sharding?jdbc進行分庫分表

    這篇文章主要介紹了SpringBoot?如何使用sharding?jdbc進行分庫分表,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • 基于Java手寫一個通用限流任務(wù)執(zhí)行器

    基于Java手寫一個通用限流任務(wù)執(zhí)行器

    調(diào)用第三方API最怕什么,那就是怕被限流,今天分享一個自制的限流任務(wù)執(zhí)行器,能幫你輕松控制請求頻率,還能自動重試失敗任務(wù),指數(shù)退避不添亂,快跟隨小編一起學(xué)習(xí)起來吧
    2026-04-04
  • SpringBoot項目動態(tài)指定配置文件的方法示例

    SpringBoot項目動態(tài)指定配置文件的方法示例

    SpringBoot 作為 Java 開發(fā)中一個非常流行的框架,以其簡化配置和快速啟動應(yīng)用而聞名,在開發(fā)過程中,我們經(jīng)常需要根據(jù)不同的環(huán)境來加載不同的配置文件,本文給大家介紹了SpringBoot項目動態(tài)指定配置文件的方法示例,需要的朋友可以參考下
    2024-12-12
  • java并發(fā)編程專題(十)----(JUC原子類)基本類型詳解

    java并發(fā)編程專題(十)----(JUC原子類)基本類型詳解

    這篇文章主要介紹了java JUC原子類基本類型詳解的相關(guān)資料,文中示例代碼非常詳細,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • SpringBoot3.4.0無法找到StringRedisTemplate?bean的問題Consider?defining?a?bean?of?type?‘org.springframework

    SpringBoot3.4.0無法找到StringRedisTemplate?bean的問題Consider?def

    本文主要介紹了SpringBoot3.4.0無法找到StringRedisTemplate?bean的問題Consider?defining?a?bean?of?type?‘org.springframework,具有一定的參考價值,感興趣的可以了解一下
    2025-03-03
  • 解決maven父子工程install的時候排除某些子模塊,讓子模塊不install問題

    解決maven父子工程install的時候排除某些子模塊,讓子模塊不install問題

    在Maven父子工程中,如果希望某個子模塊不被安裝到本地倉庫,可以在該子模塊的`pom.xml`文件中添加以下配置: ```xml ... org.apache.maven.plugins maven-install-plugin 2.5.2 true
    2024-12-12
  • Java面試官最喜歡問的關(guān)鍵字之volatile詳解

    Java面試官最喜歡問的關(guān)鍵字之volatile詳解

    這篇文章主要給大家介紹了關(guān)于Java面試官最喜歡問的關(guān)鍵字之volatile的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • MyBatis寫入Json字段以及Json字段轉(zhuǎn)對象示例詳解

    MyBatis寫入Json字段以及Json字段轉(zhuǎn)對象示例詳解

    這篇文章主要給大家介紹了關(guān)于MyBatis寫入Json字段以及Json字段轉(zhuǎn)對象的相關(guān)資料,文中通過實例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07

最新評論

合川市| 渑池县| 黑水县| 安吉县| 岐山县| 台州市| 名山县| 外汇| 中卫市| 泸定县| 铜梁县| 和田市| 石林| 镇坪县| 太湖县| 松阳县| 平舆县| 肃北| 名山县| 宜兰县| 油尖旺区| 荣昌县| 崇阳县| 隆德县| 买车| 宜兰县| 洛南县| 兴安县| 乐至县| 工布江达县| 彭州市| 株洲市| 佳木斯市| 曲周县| 衡南县| 交口县| 仁化县| 科尔| 肥东县| 丰原市| 吉木萨尔县|