微服务 第二章 CountDownLatch和Semaphone的应用

2023-09-15 22:01:04

系列文章目录

第二章 CountDownLatch和Semaphone的应用
第一章 Java线程池技术应用

在这里插入图片描述



前言

Java JUI之并发编程,CountDownLatch和Semaphone的应用

1、CountDownLatch

CountDownLatch是一个同步工具类,它通过一个计数器来实现的,初始值为线程的数量。每当一个线程完成了自己的任务,计数器的值就相应得减1。当计数器到达0时,表示所有的线程都已执行完毕,然后在等待的线程就可以恢复执行任务。
CountDownLatch(int count):count为计数器的初始值(一般需要多少个线程执行,count就设为几)。

  • CountDownLatch(int count):count为计数器的初始值(一般需要多少个线程执行,count就设为几)。
  • countDown(): 每调用一次计数器值-1,直到count被减为0,代表所有线程全部执行完毕。
  • getCount():获取当前计数器的值。
  • await(): 等待计数器变为0,即等待所有异步线程执行完毕。
  • boolean await(long timeout, TimeUnit unit):
    此方法与await()区别:
    ①此方法至多会等待指定的时间,超时后会自动唤醒,若 timeout 小于等于零,则不会等待
    ②boolean 类型返回值:若计数器变为零了,则返回 true;若指定的等待时间过去了,则返回 false

1.1、应用场景

  • 某个线程需要在其他n个线程执行完毕后再向下执行
  • 多个线程并行执行同一个任务,提高响应速度

列子:

import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
public class ThreadTest extends  Thread{

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        /*ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 2, 60, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(5), new ThreadPoolExecutor.AbortPolicy());*/

        ExecutorService executorService = Executors.newWorkStealingPool();
        //定义一个计数器
        CountDownLatch countDownLatch = new CountDownLatch(20);
        //把各个地区统计数据放到一个map里面,key:区域    value:销量 、  统计用的时间
        for (int i = 0; i < 20; i++) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    //销量统计的方法
                    countDownLatch.countDown();
                }
            };
            executorService.execute(runnable);
        }
        //等待形成全部执行完成
        countDownLatch.await();

        //把map打印出来
        log.info("end ----");
    }

}

2、Semaphone

一个计数信号量,从概念上将,信号量维护了一个许可集,如有必要,在许可可用前会阻塞每一个acquire(),然后在获取该许可。每个release()添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore只对可用许可的号码进行计数,并采取相应的行动

具体常用的方法有:

方法说明
acquire()从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断
release()释放一个许可,将其返回给信号量

设置许可数量,Semaphore semaphore = new Semaphore(3);
一般acquire()都会抛出异常,release在finally中执行

例子:
汽车抢位

public static void main(String[] args) {
    /**
     * 10辆车  4个停车位的问题
     */
    //初始化信号量
    Semaphore semaphore = new Semaphore(4);

    ExecutorService executorService = Executors.newFixedThreadPool(100);

    for (int i = 0; i < 10; i++) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    //获取许可
                    semaphore.acquire();
                    System.out.println("进入车位.....");
                    TimeUnit.SECONDS.sleep((int) (Math.random() * 10));
                    System.out.println("离开车位.....");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //释放许可
                    semaphore.release();
                }
            }
        };

        executorService.execute(runnable);

    }

}
更多推荐

【C++】动态内存管理 ① ( C 语言中的动态内存管理 | C 语言 内存申请 | C 语言 内存释放 | 代码示例 )

文章目录一、动态内存管理二、C语言中的动态内存管理1、C语言内存申请2、C语言内存释放3、代码示例-C语言动态内存管理一、动态内存管理动态内存管理由内存的申请内存的释放构成,这里的内存指的是堆内存,与之相对的是栈内存;在程序运行时过程中,经常根据需要进行动态内存管理,从而更加灵活地管理内存资源,包括:分配堆内存中的内存

优漫动游设计心得

4、团队激励优漫动游大型互联网公司一般都有一套严格的加薪制度,所以别总指望通过加薪来提升士气。那么日常团队鼓励就非常重要了。09年麦肯锡就最激励员工的因素进行的一项调查显示,排在前两位的分别是“直接领导的公开赞扬”和“领导的注意”。此外,在赞扬方面,公开赞扬也比私下赞扬对员工的正面影响要放大许多倍。因为这时你创造的不仅

C语言系统化精讲(一):C 语言开发环境搭建

文章目录一、Windows开发环境搭建1.1安装mingw编译器1.2下载并安装CLion1.3启动CLion二、Linux开发环境搭建(建议使用)2.1VMwareWorkstationPro软件简介及安装2.2安装Ubuntu系统2.2.1Ubuntu下载2.2.2安装Ubuntu2.2.3安装共享文件夹2.3概念

使用NRM管理Node镜像源,提升包下载速度

前言在日常开发中,我们经常会使用到Node.js来构建和运行JavaScript应用程序。然而,在使用Node.js时,由于网络环境的限制,我们可能会遇到包下载速度缓慢的问题。为了解决这个问题,本文将介绍如何使用NRM(NodeRegistryManager)来管理Node镜像源,从而提升包下载速度。什么是NRM?NR

JavaScript前端跨页面通信:实现页面间的数据传递与交互

🎬岸边的风:个人主页🔥个人专栏:《VUE》《javaScript》⛺️生活的理想,就是为了理想的生活!目录引言1.前端跨页面通信的概述2.前端跨页面通信的属性2.1双向通信2.2异步通信2.3安全性2.4可靠性3.前端跨页面通信的应用场景3.1多标签页间的数据共享3.2页面间的消息通知和事件触发3.3页面间的数据传

如何在Python爬虫程序中使用HTTP代理?

在进行网络爬虫时,我们经常需要使用代理服务器来隐藏自己的真实IP地址,以避免被目标网站封禁或限制访问。本文将介绍如何将HTTP代理配置到Python爬虫程序中使用。什么是HTTP代理?HTTP代理是一种网络代理,它充当客户端和服务器之间的中介,接收客户端请求并将其转发给服务器。代理服务器可以隐藏客户端的真实IP地址,使

day19正则表达式

今日内容正则表达式教学目标能够理解正则表达式的作用能够使用正则表达式的字符类能够使用正则表达式的逻辑运算符能够使用正则表达式的预定义字符类能够使用正则表达式的限定符能够使用正则表达式的分组能够在String的split方法中使用正则表达式正则表达式1.1正则表达式的概念及演示在Java中,我们经常需要验证一些字符串,例

【Flutter】2023 Google 开发者大会给 Fluter 带来了什么

文章目录一、2023年谷歌开发者大会概览二、Flutter年度进展三、Dart年度进展四、Material3年度进展五、推荐使用Flutter跨平台开发六、参考资料一、2023年谷歌开发者大会概览你知道吗,今年的谷歌开发者大会真是令人期待。从5月10日的线上GoogleI/O大会开始,到9月6日至7日在上海世博中心的现

2023年华为杯研究生数学建模竞赛辅导

2023年华为杯研究生数学建模竞赛辅导各研究生培养单位:中国研究生数学建模竞赛作为教育部学位管理与研究生教育司指导,中国学位与研究生教育学会、中国科协青少年科技中心主办的“中国研究生创新实践系列大赛”主题赛事之一,是一项面向在校研究生进行数学建模应用研究与实践的学术竞赛活动,是广大在校研究生提高建立数学模型和运用互联网

Linux多线程【线程控制】

✨个人主页:北海🎉所属专栏:Linux学习之旅🎃操作环境:CentOS7.6阿里云远程服务器文章目录🌇前言🏙️正文1、线程知识补充1.2、线程私有资源1.3、线程共享资源1.4、原生线程库2、线程控制接口2.1、线程创建2.1.1、一批线程2.2、线程等待2.3、线程终止2.4、线程实战2.5、其他接口2.5.

Flutter动态化开发之Fair实战

一、背景目前移动端应用的版本更新,最常见的方式是定期发版,无论是安卓还是iOS,都需要提交新的安装包到应用市场进行审核。审核通过后,用户在应用市场进行App的下载更新。而动态化,就是不依赖更新程序安装包,就能动态实时更新页面的技术。相比动态化技术,定期发版更新应用的方式存在一些问题,比如:审核周期长,且可能审核不通过。

热文推荐