`
bolinyang
  • 浏览: 74275 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JAVA并发编程之CyclicBarrier

阅读更多
一.概述

   使用JAVA编写并发程序的时候,我们需要仔细去思考一下并发流程的控制,如何让各个线程之间协作完成某项工作。有时候,我们启动N个线程去做一件事情,只有当这N个线程都达到某一个临界点的时候,我们才能继续下面的工作,就是说如果这N个线程中的某一个线程先到达预先定义好的临界点,它必须等待其他N-1线程也到达这个临界点,接下来的工作才能继续,只要这N个线程中有1个线程没有到达所谓的临界点,其他线程就算抢先到达了临界点,也只能等待,只有所有这N个线程都到达临界点后,接下来的事情才能继续。
    在日常工作中,我们经常和别人一起合作做一些项目,项目中有一些关键点,比如说代码联调,假如有M个开发人员,要想进行联调,这M个开发人员都必须到达这个临界点——把自己的功能模块完成,否则就无法进行联调。

二.CyclicBarrier的图示


关于上面的图片,首先A,B,C,D四个线程跑起来之后,发现向前推进的速度不一样,在某一时刻发现A,B,C已经到达临界点,但是D还没有到达临界点,此时A,B,C只能等待,当D到达临界点之后,A,B,C,D才能一起越过屏障,进行下面的工作。

三.分析一段CyclicBarrier的代码
import java.util.concurrent.CyclicBarrier;

class PerformTest {

    private int           threadCount;      // 线程数目
    private CyclicBarrier cycliBarrier;
    private int           loopCount = 10;

    public PerformTest(int threadCount){
        this.threadCount = threadCount;
        // 创建一个新的屏障,只有所有线程达到临界点之后,这里的匿名线程对象才会被执行
        this.cycliBarrier = new CyclicBarrier(this.threadCount, new Runnable() {

            /**
             * <pre>
             * 当所有线程都达到某个点的时候,这个方法就会被调用
             * </pre>
             */
            @Override
            public void run() {
                collectTestResult();
            }
        });

        for (int i = 0; i < this.threadCount; ++i) {
            Thread t = new Thread("working thread " + i) {

                @Override
                public void run() {
                    for (int j = 0; j < loopCount; ++j) {
                        doTest();
                        try {
                            /* 在这里如果发现计数值不是0的话,就会发生线程的阻塞,注意体会这里对于
                             * 对于cycliBarrier的循环利用
                             */
                            cycliBarrier.await();
                        } catch (Exception e) {
                            System.out.println(e);
                        }
                    }
                }
            };

            t.start();
        }
    }

    private void collectTestResult() {
        System.out.println("All Threads have been tested, and the result has been collected!");
    }

    private void doTest() {
        System.out.println(Thread.currentThread().getName() + " is tested!");
    }
}

public class CyclicBarrierTest1 {

    public static void main(String[] args) {
        new PerformTest(2);
    }
}


输出结果如下:
working thread 0 is tested!
working thread 1 is tested!
All Threads have been tested, and the result has been collected!
working thread 1 is tested!
working thread 0 is tested!
All Threads have been tested, and the result has been collected!
working thread 0 is tested!
working thread 1 is tested!
All Threads have been tested, and the result has been collected!
working thread 1 is tested!
working thread 0 is tested!
All Threads have been tested, and the result has been collected!
working thread 0 is tested!
working thread 1 is tested!
All Threads have been tested, and the result has been collected!
working thread 1 is tested!
working thread 0 is tested!
All Threads have been tested, and the result has been collected!
working thread 0 is tested!
working thread 1 is tested!
All Threads have been tested, and the result has been collected!
working thread 1 is tested!
working thread 0 is tested!
All Threads have been tested, and the result has been collected!
working thread 0 is tested!
working thread 1 is tested!
All Threads have been tested, and the result has been collected!
working thread 1 is tested!
working thread 0 is tested!
All Threads have been tested, and the result has been collected!


下面我们来分析一下上述这段代码的输出结果:
在程序中我们创建的两个线程,working thread 1和working thread 2。这两个线程内部都有10次for循环,cycliBarrier的总数是线程数2。线程1运行起来,在进行一次for循环之后,线程就处于等待状态,此时cycliBarrier中等待的数目变为1,由于线程处于等待状态,此时线程1无法继续向下进行,过一会working thread 2开始运行,在第一次for循环中cycliBarrier中的等待数目变为0,此时线程working thread 1被唤醒,working thread 1继续第二次循环,在第二次循环开始时,cycliBarrier就开始重复利用了,当cycliBarrier的等待数目变为0后,cycliBarrier就会恢复初始状态,进行再一次的并发流程控制。后面的运行过程是一样的,至于cycliBarrier的等待计数为0后,working thread 1和working thread 2那个先开始运行,要看具体的调度机制了。

四.CycliBarrier和CountDownLatch的区别

CycliBarrier和CountDownLatch都可以用来控制并发执行的流程,保证所有线程都做完自己的工作后在继续一些共性的工作。


1.CycliBarrier可以重复利用,但是CountDownLatch不可以重复利用。


2.CountDownLatch中计数值的递减需要自己手动去触发,但是CycliBarrier中计数值的减小是自动减小的。
  • 大小: 93.7 KB
分享到:
评论

相关推荐

    Java并发编程(CyclicBarrier)实例详解

    主要介绍了Java并发编程(CyclicBarrier)实例详解的相关资料,JAVA编写并发程序的时候,我们需要仔细去思考一下并发流程的控制,如何让各个线程之间协作完成某项工作。

    java并发编程中CountDownLatch和CyclicBarrier的使用.pdf

    java并发编程中CountDownLatch和CyclicBarrier的使用.pdf

    java并发编程中CountDownLatch和CyclicBarrier的使用借鉴.pdf

    java并发编程中CountDownLatch和CyclicBarrier的使用借鉴.pdf

    Java并发编程原理与实战

    并发工具类CyclicBarrier 详解.mp4 并发工具类Semaphore详解.mp4 并发工具类Exchanger详解.mp4 CountDownLatch,CyclicBarrier,Semaphore源码解析.mp4 提前完成任务之FutureTask使用.mp4 Future设计模式实现(实现...

    龙果 java并发编程原理实战

    龙果 java并发编程原理实战 第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四...

    Java并发编程学习笔记

    7、并发工具类CountDownLatch 、CyclicBarrier和Semaphore底层实现原理 8、线程池原理和如何使用线程池 9、ThreadLocal 为什么会内存泄漏 10、Volatile底层实现原理 11、AQS源码分析 12、CAS原理分析和使用场景 13、...

    Java并发编程基础.pdf

    Java并发编程基础主要包括以下几个核心方面: 线程与线程状态:理解Java中线程的基本概念,包括线程的创建、启动、暂停、恢复和终止。熟悉线程的生命周期及其不同状态,如新建、就绪、运行、阻塞和死亡。 线程同步...

    龙果java并发编程完整视频

    第38节并发工具类CyclicBarrier 详解00:11:52分钟 | 第39节并发工具类Semaphore详解00:17:27分钟 | 第40节并发工具类Exchanger详解00:13:47分钟 | 第41节CountDownLatch,CyclicBarrier,Semaphore源码解析00:29:57...

    Java并发编程相关技术使用案例

    1、本资源包含并发编程基础知识的使用案例,包括:线程创建、Synchronized和Reentrantlock锁的使用、线程安全问题演示、Condition的应用、CountDownLatch的应用、Cyclicbarrier的应用、Semaphore的应用、线程池的...

    Java并发编程之栅栏(CyclicBarrier)实例介绍

    主要介绍了Java并发编程之栅栏(CyclicBarrier)实例介绍,栅栏类似闭锁,但是它们是有区别的,需要的朋友可以参考下

    Java 并发编程原理与实战视频

    java并发编程原理实战 第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四个...

    汪文君高并发编程实战视频资源下载.txt

    │ Java并发编程.png │ ppt+源码.rar │ 高并发编程第二阶段01讲、课程大纲及主要内容介绍.wmv │ 高并发编程第二阶段02讲、介绍四种Singleton方式的优缺点在多线程情况下.wmv │ 高并发编程第二阶段03讲、...

    Java并发编程(22)并发新特性-障碍器CyclicBa

    Java并发编程(22)并发新特性—障碍器CyclicBarrier(含代码)编程开发技术共3页.pdf.zip

    Java并发编程(学习笔记).xmind

    Java并发编程 背景介绍 并发历史 必要性 进程 资源分配的最小单位 线程 CPU调度的最小单位 线程的优势 (1)如果设计正确,多线程程序可以通过提高处理器资源的利用率来提升系统吞吐率 ...

    Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解

    主要介绍了Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解的相关资料,需要的朋友可以参考下

    Java并发编程一CountDownLatch、CyclicBarrier、Semaphore初使用

    Java并发编程一CountDownLatch、CyclicBarrier、Semaphore初使用 CountDownLatch、CyclicBarrier、Semaphore这些线程协作工具类是基于AQS的,看完这篇博客后可以去看下面这篇博客,了解它们是如何实现的。 Java并发...

    java并发编程专题(九)----(JUC)浅析CyclicBarrier

    主要介绍了java CyclicBarrier的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下

    汪文君高并发编程实战视频资源全集

    │ Java并发编程.png │ ppt+源码.rar │ 高并发编程第二阶段01讲、课程大纲及主要内容介绍.wmv │ 高并发编程第二阶段02讲、介绍四种Singleton方式的优缺点在多线程情况下.wmv │ 高并发编程第二阶段03讲、...

    java并发编程

    第38节并发工具类CyclicBarrier 详解00:11:52分钟 | 第39节并发工具类Semaphore详解00:17:27分钟 | 第40节并发工具类Exchanger详解00:13:47分钟 | 第41节CountDownLatch,CyclicBarrier,Semaphore源码解析00:29:57...

Global site tag (gtag.js) - Google Analytics