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

Java中CyclicBarrier的理解與應用詳解

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

一、概述

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

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

二、源碼分析

//靜態(tài)內部類,用于表示屏障的狀態(tài)
private static class Generation {
        boolean broken = false;
    }
//重入鎖,用于并發(fā)場景下的加鎖和釋放鎖
    private final ReentrantLock lock = new ReentrantLock();
//通過重入鎖拿到條件對象,調用await方法會進入到條件隊列中
    private final Condition trip = lock.newCondition();
//表示線程數(shù),可以立即為這些線程數(shù)都執(zhí)行完后,屏障才會打破進入下一代
    private final int parties;
//這個是屏障被打破后,執(zhí)行的一個任務
    private final Runnable barrierCommand;
//內部內實例,存儲屏障狀態(tài)
    private Generation generation = new Generation();
  //等待執(zhí)行的線程數(shù)
    private int count;
    //進入下一代,其實就是下一個新的循環(huán),觸發(fā)條件是所有的線程都執(zhí)行完,屏障被打破時
    private void nextGeneration() {
        // signal completion of last generation
        trip.signalAll();
        // set up next generation
        count = parties;
        generation = new Generation();
    }
//打破屏障,喚醒條件隊列中線程
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;
            //如果當前的線程都執(zhí)行完畢
            if (index == 0) {  // tripped
                boolean ranAction = false;
                try {
                    final Runnable command = barrierCommand;
                    if (command != null)
                    //執(zhí)行墊底的barrierCommand方法
                        command.run();
                    ranAction = true;
                    //開始下一個循環(huán),其實也就是重置一下屏障的狀態(tài),將parties的值重新復制給count并喚醒在條件隊列中的線程
                    nextGeneration();
                    return 0;
                } finally {
                    if (!ranAction)
                    //打破屏障
                        breakBarrier();
                }
            }
			//無限循環(huán)
            for (;;) {
                try {
                    if (!timed)
                    //調用await方法等待,其實就是到了條件隊列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();
        }
    }
===================================================================================================================================
//構造函數(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,其實就是開啟一個新的循環(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();
        }
    }

三、練習

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

四、總結

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

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

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

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

相關文章

最新評論

乐都县| 揭东县| 丹凤县| 康乐县| 东莞市| 平安县| 科尔| 明光市| 鹤峰县| 安康市| 临城县| 海城市| 富裕县| 满洲里市| 洞口县| 枝江市| 延津县| 莆田市| 上杭县| 林西县| 察隅县| 马关县| 瓮安县| 柘城县| 慈溪市| 徐水县| 大新县| 龙泉市| 铜川市| 临邑县| 佛教| 饶平县| 嘉义市| 南昌县| 扎囊县| 娄底市| 和静县| 常德市| 乃东县| 梁山县| 禄劝|