CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。

  CountDownLatch是一个同步的辅助类,允许一个或多个线程,等待其他一组线程完成操作,再继续执行。

 CyclicBarrier是一个同步的辅助类,允许一组线程相互之间等待,达到一个共同点,再继续执行。

区别:CountDownLatch调用countDown()不能让线程在内部等待,也就是不能线程内部阻塞。而CyclicBarrier在调用await()方法时立刻阻塞等待其他全部的线程调用await()。

举例:

//CyclicBarrier 举例
package com.hts; import java.util.concurrent.*; public class CyclicBarrierTest {
class Task1 implements Runnable{
CyclicBarrier cyclicBarrier; Task1(CyclicBarrier cyclicBarrier){
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println("任务1开始了");
try {
System.out.println("任务1等待其他任务开始");
cyclicBarrier.await();
System.out.println("任务1执行完");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
class Task2 implements Runnable{
CyclicBarrier cyclicBarrier; Task2(CyclicBarrier cyclicBarrier){
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println("任务2开始了");
try {
System.out.println("任务2等待其他任务开始");
cyclicBarrier.await();
System.out.println("任务2执行完");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
class Task3 implements Runnable{
CyclicBarrier cyclicBarrier; Task3(CyclicBarrier cyclicBarrier){
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println("任务3开始了");
try {
System.out.println("任务3等待其他任务开始");
cyclicBarrier.await();
System.out.println("任务3执行完");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.submit(new CyclicBarrierTest().new Task1(cyclicBarrier));
executorService.submit(new CyclicBarrierTest().new Task2(cyclicBarrier));
executorService.submit(new CyclicBarrierTest().new Task3(cyclicBarrier)); }
}

执行结果:

可以看出,在线程内部一定会等待每个线程都开始了才会,全部的线程才会输出“执行完”,由此可以得出结论:所有线程在互相等待。再看看CountDownLatch例子

package com.hts;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class CountDownLatchTest {
class Task1 implements Runnable{
CountDownLatch countDownLatch; Task1(CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
System.out.println("任务1开始了");
System.out.println("任务1等待其他任务开始");
countDownLatch.countDown();
System.out.println("任务1执行完");
}
}
class Task2 implements Runnable{
CountDownLatch countDownLatch; Task2(CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
System.out.println("任务2开始了");
System.out.println("任务2等待其他任务开始");
countDownLatch.countDown();
System.out.println("任务2执行完");
}
}
class Task3 implements Runnable{
CountDownLatch countDownLatch; Task3(CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
System.out.println("任务3开始了");
System.out.println("任务3等待其他任务开始");
countDownLatch.countDown();
System.out.println("任务3执行完");
}
} public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(3);
ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.submit(new CountDownLatchTest().new Task1(countDownLatch));
executorService.submit(new CountDownLatchTest().new Task2(countDownLatch));
executorService.submit(new CountDownLatchTest().new Task3(countDownLatch)); }
}

执行结果:

可以看出,CountDownLatch不会互相等待,只会观察计数器是否到0,然后让处于await的线程执行。当然有些情况还是有通用情况,比如你在使用CyclicBarrier 时,在每个任务线程执行结束后调用await方法可以做到CountDownLatch的效果。当然CountDownLatch可以做到让某个线程等待其他线程执行到某个地方的时候就开始执行,比如主线程只需要等待其他线程任务执行一半的时候就开始执行等等。

总体来说,CountDownLatch观察计数器是否0,只有调用await的线程阻塞。CyclicBarrier 则是调用await()则开始阻塞,直到全部的线程都调用await()后开始执行。

java CyclicBarrier以及和CountDownLatch的区别的更多相关文章

  1. 循环屏障CyclicBarrier以及和CountDownLatch的区别

    CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier).它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门, ...

  2. 25.大白话说java并发工具类-CountDownLatch,CyclicBarrier,Semaphore,Exchanger

    1. 倒计时器CountDownLatch 在多线程协作完成业务功能时,有时候需要等待其他多个线程完成任务之后,主线程才能继续往下执行业务功能,在这种的业务场景下,通常可以使用Thread类的join ...

  3. 带你看看Java的锁(三)-CountDownLatch和CyclicBarrier

    带你看看Java中的锁CountDownLatch和CyclicBarrier 前言 基本介绍 使用和区别 核心源码分析 总结 前言 Java JUC包中的文章已经写了好几篇了,首先我花了5篇文章从源 ...

  4. Java并发编程:CountDownLatch、CyclicBarrier和Semaphore

    Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...

  5. Java并发编程:CountDownLatch、CyclicBarrier和Semaphore (总结)

    下面对上面说的三个辅助类进行一个总结: 1)CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同: CountDownLatch一般用于某个线程A等待 ...

  6. 14、Java并发编程:CountDownLatch、CyclicBarrier和Semaphore

    Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...

  7. 【转】Java并发编程:CountDownLatch、CyclicBarrier和Semaphore

    Java并发编程:CountDownLatch.CyclicBarrier和Semaphore   Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在j ...

  8. java CyclicBarrier同步屏障

    CyclicBarrier的字面意思是可循环使用的屏障,它的主要作用是,让一组线程到达一个屏障时被阻塞,知道最后一个线程到达屏障时,屏障才会打开,所有被屏障拦截的线程才会继续运行. 1.简介: Cyc ...

  9. Java并发工具类 - CountDownLatch

    Java并发工具类 - CountDownLatch 1.简介 CountDownLatch是Java1.5之后引入的Java并发工具类,放在java.util.concurrent包下面 http: ...

随机推荐

  1. PAT甲题题解-1101. Quick Sort (25)-大水题

    快速排序有一个特点,就是在排序过程中,我们会从序列找一个pivot,它前面的都小于它,它后面的都大于它.题目给你n个数的序列,让你找出适合这个序列的pivot有多少个并且输出来. 大水题,正循环和倒着 ...

  2. JS高级程序设计学习笔记1

    javascript产生的原因: 在拨号上网时代,表单数据必须发送到服务器端才能验证输入值得有效性,JavaScript的研发就是为了解决这个问题,以便在客户端就验证输入值的有效性. ECMAScri ...

  3. 【Beta阶段】第三次Scrum Meeting!

    每日任务内容: 本次会议为第三次Scrum Meeting会议~ 由于本次会议项目经理召开时间依旧较晚(晚上12点半),所以在公寓7层召开,女生参与了线上会议,召开时间大家集会10分钟. 队员 昨日完 ...

  4. 《Linux内核设计与实现》 第三周 读书笔记

    第一章 Linux内核简介 1. Unix的历史 Unⅸ虽然已经使用了40年,但计算机科学家仍然认为它是现存操作系统中最强大和最优秀的系统. Unix强大的根本原因: 简洁 在Unix中所有的东西都被 ...

  5. 5月29,48h,Geekathon,创业极客的梦想起点

    http://mp.weixin.qq.com/s?__biz=MjM5ODQ3MDIwMg==&mid=213768178&idx=1&sn=0a607fac483f3eab ...

  6. web项目部署在不同环境中需要修改配置文件的解决方法

    web项目部署中存在的配置文件问题: web项目以war包的形式,部署在tomcat中,同时项目需要访问一些其他的东东,例如访问数据库,调用别的项目的API.在开发中,这些需要访问的外部地址通常以配置 ...

  7. 淘宝店铺模板开发SDK2.0下载安装图文教程

    使用TortoiseSVN Checkout TAE SDK2.0 废话少说,切入主题: 1.在http://tortoisesvn.net/downloads.html上下载TortoiseSVN ...

  8. 平时在PHP编码时有没有注意到这些问题

    编出一手好代码,这个是需要你在平时开发中日积月累的,平时如果你有注意到以下的那些代码的编码,那么祝贺你,你在技能提升这方面已经垫下了一些基础,编写出一手好代码,说白了就是你特么注意到性能这块的问题,代 ...

  9. LOG4J 的配置

    公司启动全国支票影像系统,有这样一个功能是和消息中间件打交道,需要记录每一个报文出错情况,因为方便后期开发人员的调试,我选用了log4j作为日志记录,好了废话不多说了! 第一步:首先建立一个WEB工程 ...

  10. BZOJ2734 HNOI2012集合选数(状压dp)

    完全想不到的第一步是构造一个矩阵,使得每行构成公比为3的等比数列,每列构成公比为2的等比数列.显然矩阵左上角的数决定了这个矩阵,只要其取遍所有既不被2也不被3整除的数那么所得矩阵的并就是所有的数了,并 ...