CyclicBarrier:

api对CyclicBarrier的描述: 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。  也就是说他可以使一组线程先等待 然后达到某个条件之后再一起执行,有点map/reduce的感觉。

举个例子: 目前有个int,  分配3个任务线程对他加1 , 最后主任务线程汇集计算结果,代码如下:

    private static AtomicInteger i = new AtomicInteger(0);
public static void main(String[] args){
CyclicBarrier cb = new CyclicBarrier(3,new Runnable() {
//主任务汇集计算结果
public void run() {
System.out.println("结果为" + i.get());
}
});
ExecutorService es = Executors.newFixedThreadPool(5);
es.submit(new SubTask(cb, "线程一"));
es.submit(new SubTask(cb, "线程二"));
es.submit(new SubTask(cb, "线程三"));
es.shutdown();
} //子任务计算
private static class SubTask implements Runnable{
private CyclicBarrier cb;
private String msg;
public SubTask(CyclicBarrier cb, String msg){
this.cb = cb;
this.msg = msg;
}
public void run() {
try {
System.out.println(msg + " enter");
i.incrementAndGet();
Thread.sleep(1000l);
cb.await();
System.out.println(msg + " quit");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

结果:

线程一 enter
线程三 enter
线程二 enter
结果为3

线程三 quit
线程二 quit
线程一 quit

如果定义的参与者线程比实际的线程要少会怎么样? 比如上例中es提交4个任务结果会怎样?

api中描述:因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier 所以如果修改代码如下:

        CyclicBarrier cb = new CyclicBarrier(3,new Runnable() {
//主任务汇集计算结果
public void run() {
System.out.println("结果为" + i.get());
}
});
ExecutorService es = Executors.newFixedThreadPool(5);
es.submit(new SubTask(cb, "线程一"));
es.submit(new SubTask(cb, "线程二"));
es.submit(new SubTask(cb, "线程三"));
es.submit(new SubTask(cb, "线程四"));
es.shutdown();

则结果是运行完先进入的三个线程之后 第四个线程一直堵塞。

可能的输出:

线程一 enter
线程三 enter
线程二 enter
线程四 enter
结果4
线程三 quit
线程四 quit
线程一 quit

如上结果所示  有一个线程一直堵塞中

CountDownLatch:

api对CountDownLatch描述:一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用 CyclicBarrier

由此可见: CountDownLatch与CyclicBarrier的区别是: CyclicBarrier可以重复使用  而CountDownLatch不能重复使用

简单例子如下:

    public static void main(String[] args) throws InterruptedException, BrokenBarrierException{
//分配3个子任务去完成
CountDownLatch cdl = new CountDownLatch(3);
Thread t = new Thread(new SubTask(cdl, "线程1"));
Thread t1 = new Thread(new SubTask(cdl, "线程2"));
Thread t2 = new Thread(new SubTask(cdl, "线程3"));
t.start();
t1.start();
t2.start();
//在3个子任务完成之前一直等待
cdl.await();
//3个子任务完成之后 主线程获取结果
System.out.print(i.get());
} //子任务计算
private static class SubTask implements Runnable{
private CountDownLatch cb;
private String msg;
public SubTask(CountDownLatch cb, String msg){
this.cb = cb;
this.msg = msg;
}
public void run() {
i.incrementAndGet();
System.out.println(msg + "进入");
try {
Thread.sleep(1000l);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
cb.countDown();
}
}

结果:

线程2进入
线程1进入
线程3进入
3

还有一个与以上两个类使用方式非常相似的类: Semaphore

    public int MAX = 10;
public Semaphore s = new Semaphore(MAX); public void semaphoreTest() throws InterruptedException{
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try{
s.acquire(MAX);
for(int i = 0; i<MAX; i++){
s.release();
Thread.sleep(1000L);
}
}catch(Exception e){
e.printStackTrace();
}
}
});
thread.start(); Thread.sleep(1000L); while(true){
try{
s.acquire();
System.out.print(1);
}catch(Exception e){
break;
}
}
}

这个类最大的作用个人感觉就是把许可数设置为1: new Semaphore(1) 然后充当一个互斥锁。这种方式与lock比较的优势在于: lock只能有持有他的线程来释放,而semaphore实现的互斥锁可由任何线程释放,对死锁恢复非常有帮助

CyclicBarrier和CountDownLatch的使用的更多相关文章

  1. CyclicBarrier和CountDownLatch的差别

    CyclicBarrier和CountDownLatch都用多个线程之间的同步,共同点:同时有N个线程在 CyclicBarrier(CountDownLatch) 等待上等待时,CyclicBarr ...

  2. Java并发之CyclicBarrier、CountDownLatch、Phaser

    在Java多线程编程中,经常会需要我们控制并发流程,等其他线程执行完毕,或者分阶段执行.Java在1.5的juc中引入了CountDownLatch和CyclicBarrier,1.7中又引入了Pha ...

  3. 《java.util.concurrent 包源码阅读》21 CyclicBarrier和CountDownLatch

    CyclicBarrier是一个用于线程同步的辅助类,它允许一组线程等待彼此,直到所有线程都到达集合点,然后执行某个设定的任务. 现实中有个很好的例子来形容:几个人约定了某个地方集中,然后一起出发去旅 ...

  4. 使用数据库乐观锁解决高并发秒杀问题,以及如何模拟高并发的场景,CyclicBarrier和CountDownLatch类的用法

    数据库:mysql 数据库的乐观锁:一般通过数据表加version来实现,相对于悲观锁的话,更能省数据库性能,废话不多说,直接看代码 第一步: 建立数据库表: CREATE TABLE `skill_ ...

  5. JAVA多线程提高十:同步工具CyclicBarrier与CountDownLatch

    今天继续学习其它的同步工具:CyclicBarrier与CountDownLatch 一.CyclicBarrier CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公 ...

  6. java多线程开发之CyclicBarrier,CountDownLatch

    最近研究了一个别人的源码,其中用到多个线程并行操作一个文件,并且在所有线程全部结束后才进行主线程后面的处理. 其用到java.util.concurrent.CyclicBarrier 这个类. Cy ...

  7. JDK源码分析之concurrent包(四) -- CyclicBarrier与CountDownLatch

    上一篇我们主要通过ExecutorCompletionService与FutureTask类的源码,对Future模型体系的原理做了了解,本篇开始解读concurrent包中的工具类的源码.首先来看两 ...

  8. CyclicBarrier及CountDownLatch的使用

    CountDownLatch位于java.util.concurrent包下,是JDK1.5的并发包下的新特性. 首先根据Oracle的官方文档看看CountDownLatch的定义: A synch ...

  9. Android进阶——多线程系列之Semaphore、CyclicBarrier、CountDownLatch

    今天向大家介绍的是多线程开发中的一些辅助类,他们的作用无非就是帮助我们让多个线程按照我们想要的执行顺序来执行.如果我们按照文字来理解Semaphore.CyclicBarrier.CountDownL ...

  10. JAVA多线程学习十三 - 同步工具CyclicBarrier与CountDownLatch

    一.CyclicBarrier CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序 ...

随机推荐

  1. 重设SVN 的GNOME keyring [(null)] 的密码

    在ubuntu里如果改了登录密码,那么在使用svn是会要求GNOME keyring [(null)] 的密码: 去掉这个只需:rm -f ~/.gnome2/keyrings/login.keyri ...

  2. centos安装django

    1.如果默认安装的是python2.6,先升级至python2.7 参考:http://www.cnblogs.com/tiger2soft/p/5677843.html 2.安装pip 先下载get ...

  3. jQuery实现轮播切换以及将其封装成插件(2)

    在上一篇博文中,我们完成了一个简单的轮播切换.它的功能比较简单,仅仅能定时切换图片. 但是有没有这样一种情况.当我们特意的想看某一个轮播显示项时不希望等轮播一圈才能等到,希望通过图上的一些元素,触发某 ...

  4. Vue源码学习三 ———— Vue构造函数包装

    Vue源码学习二 是对Vue的原型对象的包装,最后从Vue的出生文件导出了 Vue这个构造函数 来到 src/core/index.js 代码是: import Vue from './instanc ...

  5. ES6初识-Decorator

    开始先按照个插件 npm install babel-plugin-transform-decorators-lagacy --save-dev 1.扩充和修改类的行为 2.修改的行为@readonl ...

  6. HTML5--定义区块

    1.效果图如下: 备注: <article> 1.作用:用来表示文档.页面中独立的.完整的.可以独自被外部引用的内容 2.一般有个header元素,有时还有脚注 <article&g ...

  7. Oracle_11g中解决被锁定的scott用户的方法

    在安装完Oracle10g和创建完oracle数据库之后,想用数据库自带的用户scott登录,看看连接是否成功. 问题: 在cmd命令中,用“sqlplus  scott/ tiger”登录时,老是提 ...

  8. laravel 安装excel扩展

    1,使用Composer安装依赖 在Laravel项目根目录下使用Composer安装依赖: composer require maatwebsite/excel ~2.1 ps:一定要加上~2.1! ...

  9. 深度CNN

    [具体参考可以看这里(https://cloud.tencent.com/developer/article/1369425)

  10. ln -s 软链接产生Too many levels of symbolic links错误

    不能使用相对路径, ln -s ./cmake /usr/bin/ 而是要 ln -s /usr/local/bin/cmake /usr/bin/