jdk-CyclicBarrier(二)

来源:互联网 发布:淘宝店快速提高信誉 编辑:程序博客网 时间:2024/04/29 07:31

jdk-CyclicBarrier这一篇主要是分析了它 的源码和运行图。这一篇来看看怎么运用,毕竟都是要使用的。

上文在分析源码过程中发现有个代数的问题,在nextGeneration中会有下一代的出现,这个是否就是说它是可以重用的?不然哪会来区分一代,二代,三代呢?

例子1:次例子中重复使用了CyclicBarrier

public class TestCycB {    private static int num = 3;    public static void main(String[] args) throws Exception{        final CyclicBarrier cb = new CyclicBarrier(num);        for(int i = 0; i < 3; i ++){            new EachThread(cb).start();        }        Thread.sleep(10000);        System.out.println("主线程休息够了,燥起来");        for(int i = 0; i < 3; i ++){            new EachThread(cb).start();        }    }}class EachThread extends Thread{    private CyclicBarrier cb;    public EachThread(CyclicBarrier cb){        this.cb = cb;    }    @Override    public void run() {        try{            Thread.sleep(2000);            System.out.println(Thread.currentThread().getName()+"进入等待");            cb.await();            Thread.sleep(2000);            System.out.println(Thread.currentThread().getName()+"等待结束了,执行起来");        }catch (InterruptedException e){            e.printStackTrace();        }catch (BrokenBarrierException e1){            e1.printStackTrace();        }    }}

Thread-0进入等待Thread-2进入等待Thread-1进入等待Thread-1等待结束了,执行起来Thread-0等待结束了,执行起来Thread-2等待结束了,执行起来主线程执行Thread-3进入等待Thread-5进入等待Thread-4进入等待Thread-4等待结束了,执行起来Thread-3等待结束了,执行起来Thread-5等待结束了,执行起来

例子2,使用timeout,timeout是指虽然全部线程没有完全进入,但是超过这个超时时间的话,立马执行其余线程,这些线程会抛出异常,然后继续执行.

public class TestCycB {    private static int num = 3;    public static void main(String[] args) throws Exception{        final CyclicBarrier cb = new CyclicBarrier(num);        for(int i = 0; i < 3; i ++){            Thread.sleep(3000);            new EachThread(cb).start();        }    }}class EachThread extends Thread{    private CyclicBarrier cb;    public EachThread(CyclicBarrier cb){        this.cb = cb;    }    @Override    public void run() {        System.out.println(Thread.currentThread().getName()+"进入初始化");        try{            Thread.sleep(2000);//模拟初始化            System.out.println(Thread.currentThread().getName() + "初始化结束,进入等待");            cb.await(3, TimeUnit.SECONDS);  //睡3        }catch (InterruptedException e){            e.printStackTrace();        }catch (BrokenBarrierException e1){            e1.printStackTrace();        }catch (TimeoutException e2){            e2.printStackTrace();        }        System.out.println(Thread.currentThread().getName()+"等待结束了,执行起来");    }}


Thread-0进入初始化Thread-0初始化结束,进入等待Thread-1进入初始化java.util.concurrent.TimeoutExceptionThread-1初始化结束,进入等待at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:250)Thread-0等待结束了,执行起来at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:427)Thread-1等待结束了,执行起来at concurrenttest.EachThread.run(TestCycB.java:40)java.util.concurrent.BrokenBarrierExceptionat java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:243)at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:427)at concurrenttest.EachThread.run(TestCycB.java:40)Thread-2进入初始化java.util.concurrent.BrokenBarrierExceptionat java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:200)at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:427)at concurrenttest.EachThread.run(TestCycB.java:40)Thread-2初始化结束,进入等待Thread-2等待结束了,执行起来

例子3,自定义任务,自定义任务的执行是由最终进入的线程执行的,源码中可以看见,并且这个任务是优先于其他等待线程.
public class TestCycB {    private static int num = 3;    public static void main(String[] args) throws Exception{        final CyclicBarrier cb = new CyclicBarrier(num,new Runnable() {            @Override            public void run() {                try{                Thread.sleep(5000);                }catch (Exception e){                    e.printStackTrace();                }                System.out.println(Thread.currentThread().getName()+"自带任务的执行");            }        });        for(int i = 0; i < 3; i ++){            new EachThread(cb).start();        }    }}class EachThread extends Thread{    private CyclicBarrier cb;    public EachThread(CyclicBarrier cb){        this.cb = cb;    }    @Override    public void run() {        System.out.println(Thread.currentThread().getName()+"进入初始化");        try{            Thread.sleep(2000);//模拟初始化            System.out.println(Thread.currentThread().getName() + "初始化结束,进入等待");            cb.await();        }catch (InterruptedException e){            e.printStackTrace();        }catch (BrokenBarrierException e1){            e1.printStackTrace();        }        System.out.println(Thread.currentThread().getName()+"等待结束了,执行起来");    }}

Thread-0进入初始化Thread-2进入初始化Thread-1进入初始化Thread-0初始化结束,进入等待Thread-2初始化结束,进入等待Thread-1初始化结束,进入等待Thread-2自带任务的执行Thread-0等待结束了,执行起来Thread-1等待结束了,执行起来Thread-2等待结束了,执行起来

例子4: 可以发现自带任务先执行完,最后才指向其他任务。

public class TestCycB {    private static int num = 3;    public static void main(String[] args) throws Exception{        final CyclicBarrier cb = new CyclicBarrier(num,new Runnable() {            @Override            public void run() {                try{                    Thread.sleep(10000);                }catch (Exception e){                    e.printStackTrace();                }                System.out.println("自带任务执行了");            }        });        for(int i = 0; i < 3; i ++){            new EachThread(cb).start();        }    }}class EachThread extends Thread{    private CyclicBarrier cb;    public EachThread(CyclicBarrier cb){        this.cb = cb;    }    @Override    public void run() {        System.out.println(Thread.currentThread().getName()+"进入初始化");        try{            System.out.println(Thread.currentThread().getName() + "初始化结束,进入等待");            cb.await(1, TimeUnit.SECONDS);  //睡3        }catch (InterruptedException e){            e.printStackTrace();        }catch (BrokenBarrierException e1){            e1.printStackTrace();        }catch (TimeoutException e2){            e2.printStackTrace();        }        System.out.println(Thread.currentThread().getName()+"等待结束了,执行起来");    }}

Thread-2进入初始化Thread-2初始化结束,进入等待Thread-1进入初始化Thread-1初始化结束,进入等待Thread-0进入初始化Thread-0初始化结束,进入等待自带任务执行了Thread-0等待结束了,执行起来Thread-2等待结束了,执行起来Thread-1等待结束了,执行起来


例子5:自带任务抛异常。
public class TestCycB {    private static int num = 3;    public static void main(String[] args) throws Exception{        final CyclicBarrier cb = new CyclicBarrier(num,new Runnable() {            @Override            public void run() {                try{                    Thread.sleep(6000);                    System.out.println("自带任务执行了:抛异常");                    int j = 1 /0;                }catch (Exception e){                    e.printStackTrace();                }            }        });        for(int i = 0; i < 3; i ++){            new EachThread(cb).start();        }    }}class EachThread extends Thread{    private CyclicBarrier cb;    public EachThread(CyclicBarrier cb){        this.cb = cb;    }    @Override    public void run() {        System.out.println(Thread.currentThread().getName()+"进入初始化");        try{            Thread.sleep(2000);            System.out.println(Thread.currentThread().getName() + "初始化结束,进入等待");            cb.await();  //睡3        }catch (InterruptedException e){            e.printStackTrace();        }catch (BrokenBarrierException e1){            e1.printStackTrace();        }        System.out.println(Thread.currentThread().getName()+"等待结束了,执行起来");    }}


Thread-0进入初始化Thread-2进入初始化Thread-1进入初始化Thread-2初始化结束,进入等待Thread-0初始化结束,进入等待Thread-1初始化结束,进入等待自带任务执行了:抛异常Thread-1等待结束了,执行起来Thread-2等待结束了,执行起来Thread-0等待结束了,执行起来java.lang.ArithmeticException: / by zeroat concurrenttest.TestCycB$1.run(TestCycB.java:25)at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:213)at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:355)at concurrenttest.EachThread.run(TestCycB.java:54)

最后来比较下CountDownLatch和CyclicBarrier的一些不同点。。

拿赛跑来说吧,这是个比较典型的例子。

场景1:5个人赛跑,还有一个裁判,当裁判说开始时,5个人起跑,当某一个人到达终点后,裁判按一下计数器,直至最后一个人到达,最后裁判才开始统计时间,得到每个人的时间。这个就是CountDownLatch的运用。

场景2:还是5个人赛跑,这一次没有裁判了,只规定如果5个人到达终点后,一起去喝酒这个就是CyclicBarrier的运用,此例子中没有说是否需要一起起跑,如果需要,可以加上CountDownLatch。

CountDownLatch就是一个线程等待其他线程都完成之后,再执行某些事情,强调这个。

CyclicBarrier强调线程互相等待,等待全部完成。



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果手机网站打不开怎么办 微卡怎么办货运资格证 58速运接不到单怎么办 公司亏损小股东怎么办 中铁七局拖欠农民工工资怎么办 感冒坐车耳鸣了怎么办 过隧道耳朵疼怎么办 动车耳朵不舒服怎么办 感冒坐高铁耳朵疼怎么办 坐火车耳朵难受怎么办 高铁耳朵胀痛怎么办 坐火车耳膜疼怎么办 去朝鲜的护照怎么办 朝鲜自由行签证怎么办 德国签证拒签怎么办 德签申诉不成功怎么办 出国工作找对象怎么办 白色轿车有刮痕怎么办 办签证手机钱包怎么办 怎么办美国10年签证 我没有出生证明怎么办 去台湾探亲怎么办签证 漏接澳大利亚签证电话怎么办 冰岛游公证认证怎么办 莲蓬头开关坏了怎么办 淋浴莲蓬头坏了怎么办 手机ld密码忘掉怎么办 脊椎压迫神经头晕怎么办 脊椎疼导致头晕怎么办 脊椎疼引起头晕怎么办 去英国探亲签证怎么办 地税国税合并人员怎么办 机场服务员老了怎么办 在国外没有钱了怎么办 被劫持为人质怎么办 在印度签证过期怎么办 办签证被拒怎么办 澳洲留学生怎么办新加坡签证 韩国交换生签证怎么办 没有钱还贷款怎么办 英国主动退学后怎么办