说说JUC三个类:CountDownLatch,CyclicBarrier和Semaphore

2023-11-17


在JUC中,有三个工具类来辅助我们进行并发编程,分别是 CountDownLatch,CyclicBarrier和Semaphore

CountDownLatch

英文意味倒计时器。顾名思义,它能够让某个线程等待,直到倒计时结束再执行

假如我想让主线程最后执行。看如下代码(未加CountDownLatch):

public class CountDownLatchTest {

    public static void main(String[] args) {
        int t = 5;
        for (int i = 0;i<t;i++){
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"正在执行");
            }).start();
        }
        System.out.println("主线程执行");
    }
}

---------------结果----------------
主线程执行
Thread-1正在执行
Thread-2正在执行
Thread-0正在执行
Thread-3正在执行
Thread-4正在执行

现在加上CountDownLatch

public class CountDownLatchTest {
    public static void main(String[] args) throws InterruptedException {
        int t = 5;
        CountDownLatch countDownLatch = new CountDownLatch(t);
        for (int i = 0;i<t;i++){
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"正在执行");
                countDownLatch.countDown();
            }).start();
        }
        countDownLatch.await();
        System.out.println("主线程执行");
    }
}
------------结果------------
Thread-0正在执行
Thread-2正在执行
Thread-3正在执行
Thread-1正在执行
Thread-4正在执行
主线程执行

CyclicBarrier

字面意思回环栅栏。就是让一组线程等待至同一个状态后再继续全部执行

看如下代码,假设我想让全部线程先打印第一句话后再打印第二句话,最后在打印第三句话
未加CyclicBarrier

public class CyclicBarrierTest {
    public static void main(String[] args) {
        int t = 5;
        for (int i = 0;i<t;i++){
            new Thread(()->{
                 System.out.println(Thread.currentThread().getName()+"开始执行");
                 System.out.println(Thread.currentThread().getName()+"正在执行");
                 System.out.println(Thread.currentThread().getName()+"执行完毕");
            }).start();
        }
    }
}
------------结果-------------
Thread-0开始执行
Thread-2开始执行
Thread-1开始执行
Thread-1正在执行
Thread-2正在执行
Thread-2执行完毕
Thread-1执行完毕
Thread-0正在执行
Thread-3开始执行
Thread-3正在执行
Thread-3执行完毕
Thread-4开始执行
Thread-4正在执行
Thread-4执行完毕
Thread-0执行完毕

加上CyclicBarrier

public class CyclicBarrierTest {
    public static void main(String[] args) {
        int t = 5;
        CyclicBarrier cyclicBarrier = new CyclicBarrier(t);
        for (int i = 0;i<t;i++){
            new Thread(()->{
                try {
                    System.out.println(Thread.currentThread().getName()+"开始执行");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread().getName()+"正在执行");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread().getName()+"执行完毕");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}
------------结果-------------
Thread-0开始执行
Thread-2开始执行
Thread-1开始执行
Thread-3开始执行
Thread-4开始执行
Thread-4正在执行
Thread-2正在执行
Thread-3正在执行
Thread-0正在执行
Thread-1正在执行
Thread-1执行完毕
Thread-3执行完毕
Thread-2执行完毕
Thread-4执行完毕
Thread-0执行完毕

CyclicBarrier还提供Runnable参数,可以在所有线程执行完毕后进行额外操作
代码如下:

public class CyclicBarrierTest {
    public static void main(String[] args) {
        int t = 5;
        CyclicBarrier cyclicBarrier = new CyclicBarrier(t, new Runnable() {
            @Override
            public void run() {
                System.out.println("======================");
            }
        });
        for (int i = 0;i<t;i++){
            new Thread(()->{
                try {
                    System.out.println(Thread.currentThread().getName()+"开始执行");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread().getName()+"正在执行");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread().getName()+"执行完毕");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}
-----------结果--------------
Thread-0开始执行
Thread-1开始执行
Thread-3开始执行
Thread-4开始执行
Thread-2开始执行
======================
Thread-2正在执行
Thread-0正在执行
Thread-3正在执行
Thread-1正在执行
Thread-4正在执行
======================
Thread-4执行完毕
Thread-2执行完毕
Thread-1执行完毕
Thread-3执行完毕
Thread-0执行完毕

Semaphore

意为信号量。有点像锁,是对锁的扩展。信号量可以指定多个线程同时访问一个资源,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。
假设银行有5个窗口,10个顾客,只有当窗口被释放了,下一个顾客才能去办业务;
用Semaphore的话很容易就实现

public class SemaphoreTest {
    public static void main(String[] args) {
        int t = 10;
        Semaphore semaphore = new Semaphore(5);
        for (int i = 0;i<t;i++){
            int finalI = i;
            new Thread(()->{
                try {
                    semaphore.acquire();
                    System.out.println("顾客"+ finalI +"正在办理业务,占用窗口");
                    Thread.sleep(2000);
                    System.out.println("顾客"+ finalI +"业务办理成功,释放窗口");
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}
-----------结果--------------
顾客0正在办理业务,占用窗口
顾客1正在办理业务,占用窗口
顾客2正在办理业务,占用窗口
顾客3正在办理业务,占用窗口
顾客4正在办理业务,占用窗口
顾客0业务办理成功,释放窗口
顾客5正在办理业务,占用窗口
顾客2业务办理成功,释放窗口
顾客1业务办理成功,释放窗口
顾客6正在办理业务,占用窗口
顾客7正在办理业务,占用窗口
顾客3业务办理成功,释放窗口
顾客8正在办理业务,占用窗口
顾客4业务办理成功,释放窗口
顾客9正在办理业务,占用窗口
顾客5业务办理成功,释放窗口
顾客8业务办理成功,释放窗口
顾客7业务办理成功,释放窗口
顾客9业务办理成功,释放窗口
顾客6业务办理成功,释放窗口

总结

CountDownLatch和CyclicBarrier 都能实现线程之间的等待。
CountDownLatch是让某线程在其他所有线程都执行后才执行。
CyclicBarrier是让一组相互等待到某一个阶段后再继续一起往下执行。
Semaphore有点像锁,一般用于控制对某组资源的访问权限。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

说说JUC三个类:CountDownLatch,CyclicBarrier和Semaphore 的相关文章

随机推荐

  • Keras和Tensorflow(CPU)安装、Pytorch(CPU和GPU)安装以及jupyter使用虚拟环境

    微信公众号 数学建模与人工智能 Keras和Tensorflow CPU 安装 Pytorch CPU和GPU 安装 Keras和Tensorflow CPU 安装 一 安装我用的是清华大学源 二 深度学习模型保存与加载 三 错误 Tens
  • matlab中的掩膜抠图

    改进版 矩阵中的循环操作非常耗时 so 用矩阵逻辑与操作替代for循环 one ones s img 1 s img 2 segM segM uint8 one for i 1 s img 1 for j 1 s img 2 if segM
  • 微信小程序16进制颜色码

    颜色码http www w3school com cn cssref css colornames asp
  • 时间序列算法理论及python实现(2-python实现)

    如果你在寻找时间序列是什么 如何实现时间序列 那么请看这篇博客 将以通俗易懂的语言 全面的阐述时间序列及其python实现 时间序列算法理论详见我的另一篇博客 时间序列算法理论及python实现 知 青 博客园 5 Python实现ARIM
  • ChatGPT 最好的替代品

    前两天我们邀请了微软工程师为我们揭秘 ChatGPT 直播期间有个读者问到 有了 ChatGPT BERT 未来还有发展前途吗 我想起来最近读过的一篇博客 最好的 ChatGPT 替代品 不过聊到这俩模型 就不得不提到 Transforme
  • 堆排序(Heapsort)-- 高级排序算法

    1 堆排序 Heapsort 堆排序 Heapsort 是指利用堆这种数据结构所设计的一种排序算法 二叉堆本质上是一种完全二叉树 它分为两个类型 最大堆和最小堆 最大堆任何一个父节点的值 都大于等于它左右孩子节点的值 最小堆任何一个父节点的
  • 同步(Synchronous)和异步(Asynchronous)

    概念性 同步和异步通常用来形容一次方法调用 同步方法调用一旦开始 调用者必须等到方法调用返回后 才能继续后续的行为 异步方法调用更像一个消息传递 一旦开始 方法调用就会立即返回 调用者就可以继续后续的操作 而 异步方法通常会在另外一个线程中
  • idea设置默认maven

    idea修改默认maven配置 方法一 不推荐 打开project default xml文件 在其中加入如下几行配置 代码如下 保存修改之后新建一个maven项目查看效果 方法二 新增Projects Settings 方法一 不推荐 需
  • 线性滤波器&非线性滤波器

    前言 采用线性滤波和非线性滤波是在空间域上处理图像最常用的滤波方法 matlab在处理图像滤波方面拥有可调用的函数 十分便利 我们可以根据自己的需要自行选择滤波方式对图像进行滤波 值得一提的是 图像锐化在某种程度上来说就是线性滤波 一 线性
  • emc re 整改 超标_EMC辐射骚扰超标如何整改?

    辐射骚扰是电脑 GPS导航等工作时向空间发射的一种电磁波干扰 这种干扰会影响其他电器特别是高灵敏度电器的正常工作 组成整机系统的主板 显示卡 开关电源 显示器 键盘 鼠标等都可能引起辐射骚扰超标 对于辐射骚扰通常用电磁场的大小来度量 其单位
  • 对泛型之不能协变(convariant)的理解,以及不能协变导致的问题

    1 何为协变 假设有一个接口 以及一个他的实现类 如下 接口为 public interface GenericsInterface void test 其实现类为 public class Type2 implements Generic
  • 6.ajax应用,ajax应用

    web tools ajax version 天气预报 value 北京 gt id disp weather gt ip地址查询 value 127 0 0 1 gt id disp iparea gt 手机归属查询 id disp mo
  • js利用google翻译接口把网页翻译成各国语言

    网页翻译为德语 Translate Page To German a href 网页翻译为德语 Translate Page To German a 网页翻译为西班牙语 Translate Page To Spanish a href a
  • [Mysql] 删除数据

    为了从一个数据表中删除 去掉 数据 可使用DELETE语句 语法 DELETE FROM表名 WHERE 条件 ORDER BY LIMIT row count DELETE FROM要求指定从中删除数据的表名 WHERE子句过滤要删除的行
  • 如何将li的前面那个圆点去掉

    只需要将 css样式 的 list style type 属性设置为none即可 代码如下 list style type none span style font size 18px span 下面的代码位于标签内 span style
  • 虚拟内存基本概念

    一 传统存储管理方式的特征 缺点 1 连续分配 单一连续分配 固定分区分配 动态分区分配 2 非连续分配 基本分页存储管理 基本分段存储管理 基本段页式存储管理 3 特点 很多暂时用不到的数据也会长期占用内存 导致内存利用率不高 一次性 作
  • JS基础_js一元运算符

    1 什么是一元运算符 只对一个操作数操作就能改变当前操作数的值的运算符号 2 一元运算符有哪些 2 1 正号 和负号 举例
  • CP4.矩阵的LU分解

    LU分解 将矩阵A分解成的形式 称作矩阵LU分解 L代指下三角矩阵 U代指上三角矩阵 首先用到的是前面讲过的消元法 以下为例子 通过消元操作 最后矩阵A变成了一个上三角矩阵U 那么只要上式左乘一个 就可以转化为 这里的就是L矩阵了 所以 也
  • javac编译时出现GBK报错(错误:编码GBK的不可映射字符)

    javac编译时出现GBK报错 错误 编码GBK的不可映射字符 一 这里列出我遇到的三种情况 代码格式分别为 ANSI UTF 8 无BOM的UTF 8 这里我用的是notepad 进行编写 ANSI格式 首先我们先创建一个 java源文件
  • 说说JUC三个类:CountDownLatch,CyclicBarrier和Semaphore

    目录 CountDownLatch CyclicBarrier Semaphore 总结 在JUC中 有三个工具类来辅助我们进行并发编程 分别是 CountDownLatch CyclicBarrier和Semaphore CountDow