java CyclicBarrier以及和CountDownLatch的区别
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的区别的更多相关文章
- 循环屏障CyclicBarrier以及和CountDownLatch的区别
CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier).它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门, ...
- 25.大白话说java并发工具类-CountDownLatch,CyclicBarrier,Semaphore,Exchanger
1. 倒计时器CountDownLatch 在多线程协作完成业务功能时,有时候需要等待其他多个线程完成任务之后,主线程才能继续往下执行业务功能,在这种的业务场景下,通常可以使用Thread类的join ...
- 带你看看Java的锁(三)-CountDownLatch和CyclicBarrier
带你看看Java中的锁CountDownLatch和CyclicBarrier 前言 基本介绍 使用和区别 核心源码分析 总结 前言 Java JUC包中的文章已经写了好几篇了,首先我花了5篇文章从源 ...
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore (总结)
下面对上面说的三个辅助类进行一个总结: 1)CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同: CountDownLatch一般用于某个线程A等待 ...
- 14、Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...
- 【转】Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
Java并发编程:CountDownLatch.CyclicBarrier和Semaphore Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在j ...
- java CyclicBarrier同步屏障
CyclicBarrier的字面意思是可循环使用的屏障,它的主要作用是,让一组线程到达一个屏障时被阻塞,知道最后一个线程到达屏障时,屏障才会打开,所有被屏障拦截的线程才会继续运行. 1.简介: Cyc ...
- Java并发工具类 - CountDownLatch
Java并发工具类 - CountDownLatch 1.简介 CountDownLatch是Java1.5之后引入的Java并发工具类,放在java.util.concurrent包下面 http: ...
随机推荐
- 【容器魔方解读】AWS Re:Invent 2018大会
每年云计算领域技术与商业风向标之一的AWS Re:Invent大会上周在美国拉斯维加斯召开,如往届一样,AWS密集发布了上百项的新产品或新技术.随着国内近两年云计算尤其是公有云的普及度越来越高,国内各 ...
- 《Linux内核 》MOOC 课程
姬梦馨 原创微博 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 学习笔记 一:什么是冯诺依曼体系结构? ...
- classpath与clsspath*
classpath是指 WEB-INF文件夹下的classes目录 classes含义: 1.存放各种资源配置文件 eg.init.properties log4j.properties struts ...
- DeepID1,DeepID2
1.DeepID1 (Deep Learning Face Representation from Predicting 10,000 Classes) Step1:构建网络框架 DeepConvNe ...
- Redis分布式锁的实现
前段时间,我在的项目组准备做一个类似美团外卖的拼手气红包[第X个领取的人红包最大],基本功能实现后,就要考虑这一操作在短时间内多个用户争抢同一资源的并发问题了,类似于很多应用如淘宝.京东的秒杀活动场景 ...
- jar 命令详解
jar 是随 JDK 安装的,在 JDK 安装目录下的 bin 目录中,Windows 下文件名为 jar.exe,Linux 下文件名为 jar.它的运行需要用到 JDK 安装目录下 lib 目录中 ...
- 学习构建一个简单的wcf服务
入门,构建第一个WCF程序 1.服务端 建立一个控制台应用程序作为Server,新建一个接口IData作为服务契约.这个契约接口一会儿也要放到Client端,这样双方才能遵循相同的标准.别忘了添加对 ...
- 2017-2018 ACM-ICPC, Asia Daejeon Regional Contest C(记忆化搜索)
C题 Problem C Game Map 思路: 之前暴力搜索写了好几发,一直超时,后面看其他人的题解发现要用记忆化搜索..直接暴力搜的话有太多重 复的计算. dist u 表示以u 为起点所能走的 ...
- maven项目打包时生成dependency-reduced-pom.xml
今天给maven项目打jar包,发现在pom.xml文件的同路径下,突然生出了一个dependency-reduced-pom.xml,也不知道这个文件是干什么的,看着别扭就想着删除了它. 后来知道是 ...
- 【刷题】洛谷 P4320 道路相遇
题目描述 在 H 国的小 w 决定到从城市 \(u\) 到城市 \(v\) 旅行,但是此时小 c 由于各种原因不在城市 \(u\),但是小 c 决定到在中途与小 w 相遇 由于 H 国道路的原因,小 ...