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: ...
随机推荐
- 基于Shader实现的UGUI描边解决方案
基于Shader实现的UGUI描边解决方案 前言 大扎好,我系狗猥.当大家都以为我鸽了的时候,我又出现了,这也是一种鸽.创业两年失败后归来,今天想给大家分享一个我最近研究出来的好康的,比游戏还刺激,还 ...
- 我的小游戏上线海外AppStore完整流程心得
1,购买一台Mac或者用VMWare 安装Mac OS流程,笔者使用VMWare. 先安装Mac OS 10.13,教程,成功后不要着急安装vmtools, 首先更新系统至最新版,因为真机测试往往需要 ...
- idou老师教你学Istio 17 : 通过HTTPS进行双向TLS传输
众所周知,HTTPS是用来解决 HTTP 明文协议的缺陷,在 HTTP 的基础上加入 SSL/TLS 协议,依靠 SSL 证书来验证服务器的身份,为客户端和服务器端之间建立“SSL”通道,确保数据运输 ...
- ats显示代理缓存
如果要将ats用作显示代理缓存,则必须配置客户端软件(即浏览器)以将请求直接发送到ats. 如果没有将ats配置为使用透明度选项(通过交换机或路由器在路由到源服务器的情况下拦截客户端请求并重新路由到a ...
- Day Nine
站立式会议 站立式会议内容总结 331 今天:学习plupload 遇到问题:无 明天:学习中文分词 442 今天:解决gradle以及项目计划页面的bug 遇到的问题:调用工具类以及配置gradle ...
- Java 笔记——MyBatis 生命周期
1.MyBatis 的生命周期 MyBatis的核心组件分为4个部分. SqlSessionFactoryBuilder (构造器): 它会根据配置或者代码来生成SqISessionFactory,采 ...
- c#程序阅读分析
using System; using System.Collections.Generic; using System.Text; namespace FindTheNumber { class P ...
- images & Skeleton
images & Skeleton image placeholder & loading ... skeleton.css https://github.com/dhg/Skelet ...
- Dos命令大全完整版
DOS(磁盘操作系统)命令,是DOS操作系统的命令,是一种面向磁盘的操作命令,主要包括目录操作类命令.磁盘操作类命令.文件操作类命令和其它命令. 使用技巧 DOS命令不区分大小写,比如C盘的Progr ...
- Spring MVC的路径匹配规则 Ant-style
Spring默认的策略实现了 org.springframework.util.AntPathMatcher,即Apache Ant的样式路径,Apache Ant样式的路径有三种通配符匹配方法(在下 ...