原文:https://www.jianshu.com/p/333fd8faa56e

1. CyclicBarrier 是什么?

从字面上的意思可以知道,这个类的中文意思是“循环栅栏”。大概的意思就是一个可循环利用的屏障。

它的作用就是会让所有线程都等待完成后才会继续下一步行动。

举个例子,就像生活中我们会约朋友们到某个餐厅一起吃饭,有些朋友可能会早到,有些朋友可能会晚到,但是这个餐厅规定必须等到所有人到齐之后才会让我们进去。这里的朋友们就是各个线程,餐厅就是 CyclicBarrier。

2. 怎么使用 CyclicBarrier

2.1 构造方法

  1. public CyclicBarrier(int parties)
  2. public CyclicBarrier(int parties, Runnable barrierAction)

解析:

  • parties 是参与线程的个数
  • 第二个构造方法有一个 Runnable 参数,这个参数的意思是最后一个到达线程要做的任务

2.2 重要方法

  1. public int await() throws InterruptedException, BrokenBarrierException
  2. public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException

解析:

  • 线程调用 await() 表示自己已经到达栅栏
  • BrokenBarrierException 表示栅栏已经被破坏,破坏的原因可能是其中一个线程 await() 时被中断或者超时

2.3 基本使用

2.3.1 需求

一个线程组的线程需要等待所有线程完成任务后再继续执行下一次任务

2.3.2 代码实现

  1. public class CyclicBarrierDemo {
  2. static class TaskThread extends Thread {
  3. CyclicBarrier barrier;
  4. public TaskThread(CyclicBarrier barrier) {
  5. this.barrier = barrier;
  6. }
  7. @Override
  8. public void run() {
  9. try {
  10. Thread.sleep(1000);
  11. System.out.println(getName() + " 到达栅栏 A");
  12. barrier.await();
  13. System.out.println(getName() + " 冲破栅栏 A");
  14. Thread.sleep(2000);
  15. System.out.println(getName() + " 到达栅栏 B");
  16. barrier.await();
  17. System.out.println(getName() + " 冲破栅栏 B");
  18. } catch (Exception e) {
  19. e.printStackTrace();
  20. }
  21. }
  22. }
  23. public static void main(String[] args) {
  24. int threadNum = 5;
  25. CyclicBarrier barrier = new CyclicBarrier(threadNum, new Runnable() {
  26. @Override
  27. public void run() {
  28. System.out.println(Thread.currentThread().getName() + " 完成最后任务");
  29. }
  30. });
  31. for(int i = 0; i < threadNum; i++) {
  32. new TaskThread(barrier).start();
  33. }
  34. }
  35. }

打印结果:

  1. Thread-1 到达栅栏 A
  2. Thread-3 到达栅栏 A
  3. Thread-0 到达栅栏 A
  4. Thread-4 到达栅栏 A
  5. Thread-2 到达栅栏 A
  6. Thread-2 完成最后任务
  7. Thread-2 冲破栅栏 A
  8. Thread-1 冲破栅栏 A
  9. Thread-3 冲破栅栏 A
  10. Thread-4 冲破栅栏 A
  11. Thread-0 冲破栅栏 A
  12. Thread-4 到达栅栏 B
  13. Thread-0 到达栅栏 B
  14. Thread-3 到达栅栏 B
  15. Thread-2 到达栅栏 B
  16. Thread-1 到达栅栏 B
  17. Thread-1 完成最后任务
  18. Thread-1 冲破栅栏 B
  19. Thread-0 冲破栅栏 B
  20. Thread-4 冲破栅栏 B
  21. Thread-2 冲破栅栏 B
  22. Thread-3 冲破栅栏 B

从打印结果可以看出,所有线程会等待全部线程到达栅栏之后才会继续执行,并且最后到达的线程会完成 Runnable 的任务。

3. CyclicBarrier 使用场景

可以用于多线程计算数据,最后合并计算结果的场景。

4. CyclicBarrier 与 CountDownLatch 区别

  • CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的
  • CountDownLatch 参与的线程的职责是不一样的,有的在倒计时,有的在等待倒计时结束。CyclicBarrier 参与的线程职责是一样的

CyclicBarrier 使用详解的更多相关文章

  1. CountDownLatch和CyclicBarrier 举例详解

    有时候会有这样的需求,多个线程同时工作,然后其中几个可以随意并发执行,但有一个线程需要等其他线程工作结束后,才能开始.举个例子,开启多个线程分块下载一个大文件,每个线程只下载固定的一截,最后由另外一个 ...

  2. JAVA CyclicBarrier类详解

    一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时CyclicBarrie ...

  3. java并发包java.util.concurrent详解

    线程池ThreadPoolExecutor的使用 并发容器之CopyOnWriteArrayList 并发容器之CopyOnWriteArraySet 数据结构之ConcurrentHashMap,区 ...

  4. 跟着阿里p7一起学java高并发 - 第19天:JUC中的Executor框架详解1,全面掌握java并发核心技术

    这是java高并发系列第19篇文章. 本文主要内容 介绍Executor框架相关内容 介绍Executor 介绍ExecutorService 介绍线程池ThreadPoolExecutor及案例 介 ...

  5. Mysql高手系列 - 第9篇:详解分组查询,mysql分组有大坑!

    这是Mysql系列第9篇. 环境:mysql5.7.25,cmd命令中进行演示. 本篇内容 分组查询语法 聚合函数 单字段分组 多字段分组 分组前筛选数据 分组后筛选数据 where和having的区 ...

  6. 最强Java并发编程详解:知识点梳理,BAT面试题等

    本文原创更多内容可以参考: Java 全栈知识体系.如需转载请说明原处. 知识体系系统性梳理 Java 并发之基础 A. Java进阶 - Java 并发之基础:首先全局的了解并发的知识体系,同时了解 ...

  7. java高并发系列 - 第20天:JUC中的Executor框架详解2之ExecutorCompletionService

    这是java高并发系列第20篇文章. 本文内容 ExecutorCompletionService出现的背景 介绍CompletionService接口及常用的方法 介绍ExecutorComplet ...

  8. 1.3w字,一文详解死锁!

    死锁(Dead Lock)指的是两个或两个以上的运算单元(进程.线程或协程),都在等待对方停止执行,以取得系统资源,但是没有一方提前退出,就称为死锁. 1.死锁演示 死锁的形成分为两个方面,一个是使用 ...

  9. JUC中的AQS底层详细超详解

    摘要:当你使用java实现一个线程同步的对象时,一定会包含一个问题:你该如何保证多个线程访问该对象时,正确地进行阻塞等待,正确地被唤醒? 本文分享自华为云社区<JUC中的AQS底层详细超详解,剖 ...

随机推荐

  1. Spring Boot整合UEditor不修改源码

    1.创建Springboot项目,目录结构如下(在resources中static/ueditor/jsp/config.json) 2.pom文件引入 <dependency> < ...

  2. Spring的@Autowired和@Resource注入

    @Autowired的原理 Spring@Autowired注解与自动装配 @Autowired 与@Resource的区别(详细) spring不但支持自己定义的@Autowired注解,还支持几个 ...

  3. idea 添加自定义的todo标签

    背景:idea添加自定义的todo标签可以提高开发效率,搞之 在idea定义个人风格的todo IDEA自定义TODO注释 主要分为如下两步 自定义todo标签 settings>Editor& ...

  4. jquery预加载显示百分比

    jquery预加载显示百分比 <pre> <img class="bj loadimg" loadimg="/weiqingshu/images/1/b ...

  5. [转] 下载文件旁边附的MD5/SHA256等有什么用途?

    在我们下载很多软件时,旁边会出现md5,sha1/sha256/sha512等一长串字符串,这些字符串是什么意义呢? 因为怕盗版或者怕软件被植入病毒或者插件等,要对软件的完整性做校验.步骤:先下载完软 ...

  6. 将笔记本无线网卡链接wifi通过有线网卡共享给路由器

    1.背景 背景这个就说来长了,在公司宿舍住着,只给了一个账号,每次登录网页都特别麻烦(需要账号认证那种).然后每个账号只支持一个设备在线,这就很尴尬了,那我笔记本.手机.Ipad怎么办? 当然,这时候 ...

  7. 浅谈PHP中pack、unpack的详细用法

    转自:https://segmentfault.com/a/1190000008305573 PHP中有两个函数pack和unpack,很多PHPer在实际项目中从来没有使用过,甚至也不知道这两个方法 ...

  8. javaSE总结(二)--java面向对象

    一.类和对象 (1)类 [修饰符] class 类名{ //修饰符1:private public protected 三个最多出现其一 //修饰符2:abstract final 两个最多出现其一 ...

  9. SpringBoot2.x+Redis+nginx实现session共享和负载均衡

    1.创建SpringBoot项目添加依赖 <dependency> <groupId>org.springframework.session</groupId> & ...

  10. golang ---cron

    package main import ( l4g "github.com/alecthomas/log4go" "github.com/robfig/cron" ...