CountDownLatch和CyclicBarrier你使用过吗?

简介: CountDownLatch和CyclicBarrier你使用过吗?

1 CountDownLatch

1.1 含义

一种同步辅助,允许一个或多个线程等待一组正在其他线程中执行的操作完成。CountDownLatch使用给定的计数进行初始化。由于对countDown方法的调用,await方法会阻塞,直到当前计数为零,在此之后,所有正在等待的线程都会被释放,后续对await的调用会立即返回。这是一种一次性现象——计数无法重置。如果需要重置计数的版本,可以考虑使用CyclicBarrier。

CountDownLatch是一个通用的同步工具,可以用于许多目的。初始化计数为1的CountDownLatch作为一个简单的打开/关闭锁:所有调用await的线程都在门上等待,直到它被调用countDown的线程打开。初始化为N的CountDownLatch可以用来让一个线程等待,直到N个线程完成某个动作,或者某个动作已经完成N次。

CountDownLatch的一个有用属性是,它不要求调用countDown的线程等待计数达到0后再继续,它只是阻止任何线程通过await,直到所有线程都可以通过。

1.2 使用场景举例

公司要选择一个办公室开董事会,董事会共有股东十个人,需要等每个股东都要到办公室才能开会,我们把每个股东视为一个线程,把开会这个事件视为主线程。

网络异常,图片无法展示
|


1.3 代码实现

/**
 * @desc: JUC CountDownLatch应用场景
 * @author: YanMingXin
 * @create: 2021/7/31-10:24
 **/
public class Test01 {
    public static void main(String[] args) throws InterruptedException {
        //公司开会需要集齐董事会10个人,10个人不分先后,只要来齐了才能开会
        CountDownLatch latch = new CountDownLatch(10);
        //十个人每个人一个线程
        for (int i = 0; i <= 10; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "到场");
                //增加一个人
                latch.countDown();
            }, String.valueOf(i)).start();
        }
        //主线程等待
        latch.await();
        System.out.println("开始开会......");
    }
}
复制代码

测试结果

网络异常,图片无法展示
|


2 CyclicBarrier

2.1 含义

一种同步辅助,它允许一组线程都等待彼此到达一个共同的障碍点。CyclicBarrier在涉及固定大小的线程的程序中非常有用,这些线程偶尔必须相互等待。这个屏障被称为循环屏障,因为在等待的线程被释放后,它可以被重用。

CyclicBarrier支持一个可选的Runnable命令,该命令在每个barrier点运行一次,在该组的最后一个线程到达之后,但在任何线程被释放之前。这个barrier操作对于在任何一方继续之前更新共享状态非常有用。

2.2 使用场景举例

公司开完董事会后,为了保证安全性需要将办公室锁起来,当然锁门之前需要每个人都要走出来,我们仍旧把每个人当作一个线程,把锁门的事件当做主线程。

网络异常,图片无法展示
|


2.3 代码实现

/**
 * @desc: JUC CyclicBarrier
 * @author: YanMingXin
 * @create: 2021/7/31-10:31
 **/
public class Test02 {
    public static void main(String[] args) {
        //公司董事会开完会要等全部出去才能锁门
        CyclicBarrier barrier = new CyclicBarrier(10, () -> {
            System.out.println("办公室锁门......");
        });
        for (int i = 1; i <= 10; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName());
                try {
                    //等待锁门
                    barrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, String.valueOf(i)).start();
        }
    }
}
复制代码

测试结果:

网络异常,图片无法展示
|


3 结语

当然以上的使用场景是最常见的,以后有时间的话还要研究下CountDownLatch和CyclicBarrier的其他使用场景和原理,敬请期待哦!


相关文章
|
存储 安全
office软件2016版本下载安装教程——office全版本软件安装包
office软件2016版本下载安装教程——office全版本软件安装包
950 0
|
算法 搜索推荐 Python
Python算法——基数排序
Python算法——基数排序
144 1
|
传感器 人工智能 物联网
柔性电子技术:可穿戴设备与智能生活的未来
【9月更文挑战第14天】柔性电子技术作为一种新兴且充满潜力的技术,正逐步成为连接可穿戴设备与智能生活的桥梁。它以其独特的灵活性和适应性,为我们的生活带来了更多的可能性和便捷性。尽管目前仍面临诸多挑战,但随着科技的不断进步和创新的推动,柔性电子技术必将迎来更加美好的未来。
|
存储 安全 Java
Java Queue:从入门到精通,一篇文章就够了!
【6月更文挑战第18天】Java集合框架中的队列Queue遵循FIFO原则,用于存储和管理元素。从创建队列(如LinkedList示例)到移除元素(remove和poll方法),再到不同实现类(如ArrayDeque和ConcurrentLinkedQueue),队列在多线程、任务调度等场景中广泛应用。自定义队列如LimitedQueue展示如何限制容量。了解并熟练使用队列能提升程序性能和可读性。队列,是高效编程的关键工具。
310 1
|
算法 定位技术
GPS信号的数字接收处理matlab仿真,包括频率点搜索,捕获跟踪,相关峰检测等步骤
GPS信号的数字接收处理matlab仿真,包括频率点搜索,捕获跟踪,相关峰检测等步骤
|
存储 开发框架 人工智能
Python编程入门:从基础到实战
【8月更文挑战第27天】本文将引导您进入Python编程的奇妙世界,从最基础的语法开始,逐步深入到数据处理和Web开发等领域。我们将通过实际代码示例,展示如何用Python解决实际问题,让您在阅读过程中不仅能学到知识,还能获得实践的乐趣。
|
安全 C语言
【C语言】动态通讯录 -- 详解
【C语言】动态通讯录 -- 详解
|
存储 Java API
重温经典《Thinking in java》第四版之第二章 一切都是对象(十二)
重温经典《Thinking in java》第四版之第二章 一切都是对象(十二)
148 1
|
缓存 调度 Nacos
04篇 Nacos Client服务订阅机制之【核心流程】
04篇 Nacos Client服务订阅机制之【核心流程】
1270 0
04篇 Nacos Client服务订阅机制之【核心流程】
|
SQL 数据挖掘 Python
【边学边敲边记】LeetCode006:三数之和
【边学边敲边记】LeetCode006:三数之和
140 0
【边学边敲边记】LeetCode006:三数之和