博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java核心-多线程-并发控制器-CyclicBarrier同步屏障
阅读量:5272 次
发布时间:2019-06-14

本文共 3079 字,大约阅读时间需要 10 分钟。

1.基本概念

中文译本同步屏障,同样来自jdk并发工具包中一个并发控制器,它的使用和CountDownLatch有点相似,能够完成某些相同并发场景,但是它们却不相同。

2.抽象模型

主要用来实现多个线程同步,同步后可能唤醒另外一个任务,然后继续执行线程后面的任务。CountDownLatch抽象模型却是一个或多个线程通知某个或多个线程,它没有同步功能。

3.使用场景

田径比赛, 虽然上一篇文章使用CountDownLatch也能实现,但是我觉得这里却使用同步屏障更简单点。

4.CyclicBarrier使用api

java new CyclicBarrier(int parties); //创建同步屏障,仅仅启动同步作用,中间没有需要执行的任务。
java new CyclicBarrier(int parties, Runnable barrierAction); //创建同步屏障,不仅同步,而且中间有任务需要执行。
java cyclicBarrier.await(); //调用一次,parties就会减1,直到变为0时,执行barrierAction任务后(配置情况下),然后执行此代码的线程才能停止阻塞,继续执行。
java ps:因为使用CyclicBarrier的线程都会阻塞在await方法上,所以在线程池中使用CyclicBarrier时要特别小心,如果线程池的线程过少,那么就会发生死锁了。

5.使用示例(田径比赛)

public static void main(String[] args) {        ExecutorService executor = Executors.newFixedThreadPool(3);        final CyclicBarrier startBarrier = new CyclicBarrier(3, new Runnable() {            @Override            public void run() {                                try {                    System.out.println("他们都准备好了,那就开跑吧");                    System.out.println("3");                    Thread.sleep(1000);                    System.out.println("2");                    Thread.sleep(1000);                    System.out.println("1");                    Thread.sleep(1000);                    System.out.println("0");                    System.out.println("go!!!");                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        });        CyclicBarrier endBarrier = new CyclicBarrier(3, new Runnable() {            @Override            public void run() {                System.out.println("都到达了终点,比赛结束");            }        });        for(int i=3;i>0;i--){            final int num = i;            Runnable runnable = new Runnable() {                                @Override                public void run() {                    try {                        int time = (int)(Math.random()*1000);                        Thread.sleep(time);                        System.out.println("运动员" + num + "号,准备了" + time + "ms,准备结束!");                        startBarrier.await();                        System.out.println("运动员" + num + "号,开始跑了");                        int runtime = (int)(Math.random()*10000);                        Thread.sleep(runtime);                        System.out.println("运动员" + num + "号,用时:" + runtime + "ms");                        endBarrier.await();                    } catch (Exception e) {                        e.printStackTrace();                    }                }            };            executor.submit(runnable);        }    }

执行结果

运动员1号,准备了580ms,准备结束!运动员3号,准备了866ms,准备结束!运动员2号,准备了878ms,准备结束!他们都准备好了,那就开跑吧3210go!!!运动员2号,开始跑了运动员1号,开始跑了运动员3号,开始跑了运动员2号,用时:2008ms运动员3号,用时:5587ms运动员1号,用时:6634ms都到达了终点,比赛结束

6.和CountDownLatch的区别

<1>CountDownLatch能唤醒多个线程,而CyclicBarrier只能唤醒一个线程;
<2>一个线程或多个线程(A)使用CountDownLatch通知另外一个或多个线程(B),A线程之间不会有同步功能,需要多个latch才能实现同步功能;而CyclicBarrier能同步A线程组的执行步骤;
<3>CountDownLatch是一次性的,不能重置,而CyclicBarrier不是,它有reset()方法;

转载于:https://www.cnblogs.com/leeethan/p/10680835.html

你可能感兴趣的文章
软件开发与模型
查看>>
161017、SQL必备知识点
查看>>
kill新号专题
查看>>
MVC学习系列——Model验证扩展
查看>>
mysqladmin 修改和 初始化密码
查看>>
字符串
查看>>
vue2.x directive - 限制input只能输入正整数
查看>>
实现MyLinkedList类深入理解LinkedList
查看>>
自定义返回模型
查看>>
C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 客户端多网络支持
查看>>
HDU 4122
查看>>
Suite3.4.7和Keil u3自带fx2.h、fx2regs.h文件的异同
查看>>
打飞机游戏【来源于Crossin的编程教室 http://chuansong.me/account/crossincode 】
查看>>
[LeetCode] Merge Intervals
查看>>
【翻译自mos文章】当点击完 finishbutton后,dbca 或者dbua hang住
查看>>
Linux编程简介——gcc
查看>>
2019年春季学期第四周作业
查看>>
MVC4.0 利用IActionFilter实现简单的后台操作日志功能
查看>>
rotate the clock
查看>>
bugku 变量
查看>>