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. 再探Redux Middleware

    前言 在初步了解Redux中间件演变过程之后,继续研究Redux如何将中间件结合.上次将中间件与redux硬结合在一起确实有些难看,现在就一起看看Redux如何加持中间件. 中间件执行过程 希望借助图 ...

  2. Redis学习笔记之入门基础知识——五种数据类型

    1) 字符串 SET设置值,GET获取值,DEL删除值 INCR key-name将键存储的值加上1       DECR key-name将键存储的值减去1 INCRBY key-name amou ...

  3. SDN可靠性相关

    A subtree-based approach to failure detection and protection for multicast in SDN FRONTIERS OF INFOR ...

  4. Leetcode题库——47.全排列II

    @author: ZZQ @software: PyCharm @file: permuteUnique.py @time: 2018/11/16 13:34 要求:给定一个可包含重复数字的序列,返回 ...

  5. AIX上安装配置DB2

    在2台P550数据库主机上安装DB2 V8.2,两台数据库主机间进行数据库HA配置,实现数据库双机互备. 本文档编写以磁盘大小360G,数据库名CRAMS_JS为例. 设备准备 请系统管理员协助划分D ...

  6. css3-文本新增属性

    rgba:a是设透明度值 应用:background:rgb(255,255,255,0.5) color:rgb(255,255,255,0.5) border:1px solid rgb(255, ...

  7. [CB] 支付宝区块链的应用- 区块链发票医保理赔.

    全国第一单区块链理赔.发票开出:1分钟报销     区块链技术和概念随着比特币等虚拟电子货币的兴起而尽人皆知,但是区块链的用途可不仅仅只玩币,尤其是在“矿难”到来之后,区块链正在向更多应用领域渗透.最 ...

  8. [转帖]Mysql 开启跟踪的一个方法

    MySQL 事件跟踪器 , MySQL 无须重启服务 跟踪 SQL , 也无须配置日志 原博客地址: https://www.cnblogs.com/wuyifu/p/3328024.html 第一步 ...

  9. 【Vue学习笔记1】全局配置 Vue.config

    1.slient 类型:boolean: 默认:false: 用法:Vue.config.silent = true  用于取消 Vue 所有的日志与警告

  10. 【版本管理】自定义git

    Git除了可配置user.name和user.email外,实际上,Git还有很多可配置项. 如 $ git config --global color.ui true,让Git显⽰示颜⾊色,会让命令 ...