并发编程系列之CountDownLatch用法简介

举报
yd_273762914 发表于 2021/11/29 23:43:59 2021/11/29
【摘要】 1、 CountDownLatch倒计数锁存器 CountDownLatch:用于协同控制一个或多个线程等待在其他线程中执行的一组操作完成,然后再继续执行 2、 CountDownLatch用法 构...

1、 CountDownLatch倒计数锁存器

CountDownLatch:用于协同控制一个或多个线程等待在其他线程中执行的一组操作完成,然后再继续执行

2、 CountDownLatch用法

  • 构造方法:CountDownLatch(int count),count指定等待的条件数(任务数、操作数),不可再更改
  • 等待方法:await(),阻塞等待线程直到count减少为0,count为0时,不会阻塞,继续执行
  • boolean await(long timeout,TimeUnit unit):可以设置超时时间的await方法,返回true表示等待条件到达;false表示条件未来到达,但超时了
  • long getCount():获取当前计数值,常用于调试或者测试

CountDownLatch注意事项:只可使用一次,不能重复使用,计数变为0之后,就不可再用

3、CountDownLatch适用场景

  1. 等待多个条件完成,countDownLatch(N)这个多个条件可以是:等待N个线程、等待N个操作、等待某操作的N次执行
  2. 用于并发测试,等待多个线程一起出发

4、CountDownLatch例子

例子:等待n个线程执行完成,再一起执行


import java.util.Random;
import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {

    public static void main(String[] args) {

        final CountDownLatch cdl = new CountDownLatch(1);

        int concurrency = 100;
        final Random random = new Random();
        for (int i = 0; i < concurrency; i++) {
            new Thread(()->{
                try {
                    Thread.sleep(random.nextInt(10_000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "准备就绪");
                // 让并发线程都等待发出信号
                try {
                    cdl.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "开始工作");
            }).start();
        }
        System.out.println("******************** 发出开始信号***********");
        cdl.countDown();
    }
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

执行,发现结果不符合我们的要求,虽然也是多个线程等待,再一起无序执行:

******************** 发出开始信号***********
Thread-22准备就绪
Thread-22开始工作
Thread-45准备就绪
Thread-45开始工作
...

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

因为CountDownLatch不能重用,所以再新加一个CountDownLatch协同N个线程:


import java.util.Random;
import java.util.concurrent.CountDownLatch;

public class StartTogerCountdownLatchExample {

    public static void main(String[] args) throws InterruptedException {
        final CountDownLatch cdl = new CountDownLatch(1);
        int concurrency = 100;
        final CountDownLatch cdln = new CountDownLatch(concurrency);
        final Random random = new Random();
        for (int i = 0;i < concurrency; i++) {
            new Thread(()->{
                try {
                    Thread.sleep(random.nextInt(10_000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(
                        Thread.currentThread().getName() + " 准备就绪");
                // 调用countDown()报告完成任务
                cdln.countDown();
                // 让所有线程都等待发出信号
                try {
                    cdl.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(
                        Thread.currentThread().getName() + " 开始工作");
            }).start();
        }
        //等待准备完成
        cdln.await();
        System.out.println("******************** 发出开始信号***********");
        cdl.countDown();
    }
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

等待N个线程准备就绪,然后一个总的CountDownLatch发出信号量,所有线程一起执行

...
Thread-11 准备就绪
Thread-14 准备就绪
Thread-53 准备就绪
Thread-91 准备就绪
******************** 发出开始信号***********
Thread-97 开始工作
Thread-57 开始工作
...

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

文章来源: smilenicky.blog.csdn.net,作者:smileNicky,版权归原作者所有,如需转载,请联系作者。

原文链接:smilenicky.blog.csdn.net/article/details/121612631

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。