CyclicBarrier和CountDownLatch区别

CyclicBarrier和CountDownLatch区别这两天写多线程时,用到了CyclicBarrier,下意识的认为CyclicBarrier和CountDownLatch作用很像,就翻阅资料查了一下,说一下他们的区别吧CyclicBarrier和CountDownLatch都位于java.util.concurrent这个包下CountDownLatchCyclicBarrier

大家好,又见面了,我是你们的朋友全栈君。

这两天写多线程时,用到了CyclicBarrier,下意识的认为CyclicBarrier和CountDownLatch作用很像,就翻阅资料查了一下,说一下他们的区别吧

CyclicBarrier和CountDownLatch 都位于java.util.concurrent 这个包下

CountDownLatch CyclicBarrier
减计数方式 加计数方式
计算为0时释放所有等待的线程 计数达到指定值时释放所有等待线程
计数为0时,无法重置 计数达到指定值时,计数置为0重新开始
调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响 调用await()方法计数加1,若加1后的值不等于构造方法的值,则线程阻塞
不可重复利用 可重复利用


一、CountDownLatch用法

CountDownLatch类只提供了一个构造器:

public CountDownLatch(int count) {  };  //参数count为计数值

然后下面这3个方法是CountDownLatch类中最重要的方法:

public void await() throws InterruptedException { };   //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };  //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public void countDown() { };  //将count值减1

CountDownLatch, 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。

下面举个例子说明:

package main.java.CountDownLatch;

import java.util.concurrent.CountDownLatch;

/**
 * PROJECT_NAME:downLoad
 * Author:lucaifang
 * Date:2016/3/18
 */
public class countDownlatchTest {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(5);
        for(int i=0;i<5;i++){
            new Thread(new readNum(i,countDownLatch)).start();
        }
        countDownLatch.await();
        System.out.println("线程执行结束。。。。");
    }

    static class readNum  implements Runnable{
        private int id;
        private CountDownLatch latch;
        public readNum(int id,CountDownLatch latch){
            this.id = id;
            this.latch = latch;
        }
        @Override
        public void run() {
            synchronized (this){
                System.out.println("id:"+id);
                latch.countDown();
                System.out.println("线程组任务"+id+"结束,其他任务继续");
            }
        }
    }
}

输出结果:

id:1
线程组任务1结束,其他任务继续
id:0
线程组任务0结束,其他任务继续
id:2
线程组任务2结束,其他任务继续
id:3
线程组任务3结束,其他任务继续
id:4
线程组任务4结束,其他任务继续
线程执行结束。。。。

线程在countDown()之后,会继续执行自己的任务,而CyclicBarrier会在所有线程任务结束之后,才会进行后续任务,具体可以看下面例子。

二、CyclicBarrier用法

CyclicBarrier提供2个构造器:

public CyclicBarrier(int parties, Runnable barrierAction) {
}
 
public CyclicBarrier(int parties) {
}

参数parties指让多少个线程或者任务等待至barrier状态;参数barrierAction为当这些线程都达到barrier状态时会执行的内容。

CyclicBarrier中最重要的方法就是await方法

public int await() throws InterruptedException, BrokenBarrierException { };//挂起当前线程,直至所有线程都到达barrier状态再同时执行后续任务;
public int await(long timeout, TimeUnit unit)throws InterruptedException,BrokenBarrierException,TimeoutException { };//让这些线程等待至一定的时间,如果还有线程没有到达barrier状态就直接让到达barrier的线程执行后续任务

举例说明

package main.java.countOff;

import java.util.concurrent.CyclicBarrier;

/**
 * PROJECT_NAME:downLoad
 * Author:lucaifang
 * Date:2016/3/18
 */
public class cyclicBarrierTest {
    public static void main(String[] args) throws InterruptedException {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
            @Override
            public void run() {
                System.out.println("线程组执行结束");
            }
        });
        for (int i = 0; i < 5; i++) {
            new Thread(new readNum(i,cyclicBarrier)).start();
        }
        //CyclicBarrier 可以重复利用,
        // 这个是CountDownLatch做不到的
//        for (int i = 11; i < 16; i++) {
//            new Thread(new readNum(i,cyclicBarrier)).start();
//        }
    }
    static class readNum  implements Runnable{
        private int id;
        private CyclicBarrier cyc;
        public readNum(int id,CyclicBarrier cyc){
            this.id = id;
            this.cyc = cyc;
        }
        @Override
        public void run() {
            synchronized (this){
                System.out.println("id:"+id);
                try {
                    cyc.await();
                    System.out.println("线程组任务" + id + "结束,其他任务继续");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

输出结果:

id:1
id:2
id:4
id:0
id:3
线程组执行结束
线程组任务3结束,其他任务继续
线程组任务1结束,其他任务继续
线程组任务4结束,其他任务继续
线程组任务0结束,其他任务继续
线程组任务2结束,其他任务继续

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158669.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • MATLAB绘制三维图形z=5_plot3用法

    MATLAB绘制三维图形z=5_plot3用法matlab绘制三维图形(mesh,surf,contour,fimplicit3)

    2022年8月31日
    5
  • 至尊问题「建议收藏」

    称号:已知m、n为整数,且满足下列两个条件:① m、n∈1,2,…,K,(1≤K≤10^9)② (n^ 2-mn-m^2)^2=1编一程序,对给定K,求一组满足上述两个条件的m、n,而且使m^2+n^2的值最大。比如,若K=1995,则m=987,n=1597,则m、n满足条件,且可使m^2+n^2的值最大。输入输入仅一行,K的值。输出…

    2022年4月13日
    45
  • C++写一个CSGO开箱模拟器「建议收藏」

    C++写一个CSGO开箱模拟器「建议收藏」head玩过csgo的人类都知道,开箱是很有趣的。————名人名言Appstore上有专门的开箱模拟器,但是啊,他有广告。(;′⌒`)所以心善的博主决定自己用C++手撸一款开箱模拟器:3A大作,有整整一种箱子可供选择附加开箱动画,效果及其逼真…

    2022年9月28日
    2
  • Spring的基本配置和Spring与Mybatis的整合

    Spring的基本配置和Spring与Mybatis的整合Spring:        Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架,由RodJohnson在其著作ExpertOne-On-OneJ2EEDevelopmentandDesign中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪…

    2022年4月29日
    40
  • 【详细+超基础】Java-学习笔记

    【详细+超基础】Java-学习笔记JAVA简介Java是半编译半解释性语言,它将.java的源程序文件编译成拓展名为.class的字节码文件,字节码文件可以在任何一台装有JVM虚拟机的操作系统上运行,从而达到“一次编译,随处运行”的目的。Java特点:简单的面向对象的分布式的解释执行的健壮的安全的结构中立的可移植的高效率的多线程的动态的和跨平台的编程语言。……

    2022年8月31日
    3
  • C#异步调用的方法

    最经公司工作需要调用一个外部的webservice,同时要将传出的数据进行保存,以自己以前的习惯,就打算逐步操作,失败啊,完全没考虑过用户体验效果,在同事指点下,意识到使用异步调用的好处,随便将自己找

    2021年12月24日
    38

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号