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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • JSONPath表达式

    JSONPath表达式前言JSONPath是一种简单的方法来提取给定JSON文档的部分内容。JSONPath提供的json解析非常强大,它提供了类似正则表达式的语法,基本上可以满足所有你想要获得的json内容。JSONPath表达式语法1、操作符?:问号,标记表达式的开头。使用的语法[?(表达)]例如:[?(Expression)]@:在符号处表示正在处理的当前节点。语法使用$.books[?@.price>100]注意:使用JSONPath的[]操作符操作一个对象或者数组,索引是从0开始。

    2022年6月24日
    189
  • 黑苹果MacOS Big Sur 11.0 安装教程及驱动工具

    黑苹果MacOS Big Sur 11.0 安装教程及驱动工具最新黑苹果MacOSBigSur11.0安装教程,附带各电脑EFI驱动合集、原版引导镜像,图文并茂简单易懂…一、准备工作1.一个8G以上的U盘(安装10.15Catalina必须要16G及以上的U盘);2.MacOS镜像、TransMac(刻录工具)、DiskGenius(分区工具)、EasyUEFI(引导工区)、EFI驱动文件。安装工具获取链接:https://pan.baidu.com/s/1pwUVVo1Ud4yxO29k_ckTBw提取码:qs05安装镜像

    2022年6月3日
    160
  • Java设计模式之迭代子模式

    本文继续介绍23种设计模式系列之观察者模式。定义在软件构建过程中,集合对象内部结构常常变化各异,但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素;同时这种“透明遍历”也为同一种算法在多种集合对象上进行操作提供了可能。使用面向对象技术将这种遍历机制抽象为“迭代器对象”为“应对变化中的集合对象”提供了一种优雅的方式。迭代子(Iterator)模式又叫游标

    2022年3月11日
    37
  • GMT时间格式转换(Mon Feb 13 08:00:00 GMT+08:00 2012)

    GMT时间格式转换(Mon Feb 13 08:00:00 GMT+08:00 2012)普通的时间转换问题我这里就不再罗嗦了 我想大家应该都会那种低级的转换问题吧 现在我向大家总结一下如何转换 GMT 时间格式 这种格式的转换方法网上还不是很多 所以有必要总结一下 也算给有需要的朋友一个小小的帮助啦 首先先来了解一下 GMT 的时间格式 MonFeb1308 00 00GMT 08 002012 可能还会有其他的格式类似 SunSep0 00 00G

    2025年6月14日
    3
  • ubuntu过期版本软件源[通俗易懂]

    ubuntu过期版本软件源[通俗易懂]ubuntu10.04软件源国内源,参考:https://blog.csdn.net/snaking616/article/details/52966634debhttp://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/lucidmainrestricteduniversemultiversedebhttp://mi…

    2022年10月14日
    5
  • 给定一个n个正整数组成的数组_求数组最小差值最优算法

    给定一个n个正整数组成的数组_求数组最小差值最优算法给定长度为 N 的数列 A,然后输入 M 行操作指令。第一类指令形如 C l r d,表示把数列中第 l∼r 个数都加 d。第二类指令形如 Q x,表示询问数列中第 x 个数的值。对于每个询问,输出一个整数表示答案。输入格式第一行包含两个整数 N 和 M。第二行包含 N 个整数 A[i]。接下来 M 行表示 M 条指令,每条指令的格式如题目描述所示。输出格式对于每个询问,输出一个整数表示答案。每个答案占一行。数据范围1≤N,M≤105,|d|≤10000,|A[i]|≤109输

    2022年8月10日
    21

发表回复

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

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