多线程应用——阻塞队列

阻塞队列

文章目录

  • 阻塞队列
    • 1.队列的概念
    • 2.阻塞队列
    • 3.现实中的例子
    • 4.消息队列
    • 5.使用队列的优势
      • 1.解耦
      • 2.削峰填谷
      • 3.异步操作
    • 6.实现

1.队列的概念

一种先进先出的数据结构

2.阻塞队列

队列写元素是从队尾插入,从对头取出

当插入元素时,先判断一下队列是否已满,如果满了就等待(阻塞),等到队列中有空余位置时再插入

当取出元素时,先判断一下队列是否为空,如果空了就等待(阻塞),等到队列中有元素时再去取出

3.现实中的例子

包饺子:

  1. 和面
  2. 擀皮
  3. 包饺子

两种分配方式

  1. 各干各的,每个人都擀皮,包饺子,这是会产生严重的锁竞争
  2. 一个人专门负责擀皮,其他人包饺子,常用的方式,提高效率

这里涉及到一个模型,生产者消费者模型

擀皮的那个人是生产者,其他包饺子的人是消费者,放饺子皮的地方是交易场所

生产者消费者模型利用阻塞队列解决了锁竞争可能产生的冲突的问题,而且还有其他优势

4.消息队列

在阻塞队列的基础上对消息进行分组

5.使用队列的优势

1.解耦

高内聚,低耦合

高内聚:业务强相关的功能或代码组织在一起,不要在这个类里一个方法,那个类里一个方法,为了后续维护方便,设计与组织的一种方式

低耦合:不强相关的代码,或是重复代码,尽量抽象成其他的接口,在各个方法中调用就可以了。

image-20230902192904540

image-20230902194115919

2.削峰填谷

削峰:在流量暴增的时候用消息队列把消息缓存起来,后面的服务器一点一点按正常速度处理

提谷:消费消息的服务器在流量不多的情况下,处理之前堆积的消息,这个就是填谷

例如:淘宝双十一,订单消息量过大,物流、银行等服务不能及时处理,消费服务器就可以按照其他业务的API流量限制处理消息

3.异步操作

同步是指的是一次只能完成一件任务。如果有多任务,就必须排队,前面一个任务完成,再执行后面一个任务

异步指的是每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

6.实现

在JDK中为我们提供了关于阻塞队列的接口BlockingQueue

这里我们通过一个数组来实现阻塞队列

public class MyBlockingQueue {
    //用数组来保存数据
    private Integer[] elementData=new Integer[1000];
    //队尾与队首的下标
    private volatile int head=0;
    private volatile int tail=0;
    //有效元素个数
    private volatile int size=0;


    /**
     * 添加元素
     * @param value
     */
    public void put(Integer value) throws InterruptedException {

        synchronized (this){
            //先判断队列是否满了
            //解决虚假唤醒问题
            while (size>=elementData.length){
                //队列已满就阻塞等待
                this.wait();
            }
            //从队尾入队
            elementData[tail]=value;
            //队尾下标向前移动
            tail++;
            if(tail>=elementData.length){
                tail=0;
            }
            //修改有效个数
            size++;

            //添加新元素之后,唤醒其他线程
            this.notifyAll();
        }

    }


    /**
     * 获取元素
     * @return
     */
    public Integer take() throws InterruptedException {
        synchronized (this){
            //先判断队列是否为空
            while (size == 0) {
                //出队时,如果为空就等待
                this.wait();
            }
            //出队队首元素
            Integer value=elementData[head];
            //向后移动head
            head++;
            if (head>= elementData.length){
                head=0;
            }
            //修改有效元素的个数
            size--;
            //出队时唤醒其他线程
            this.notifyAll();
            return value;
        }

    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/101837.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

com.squareup.okhttp3:okhttp 组件安全漏洞及健康度分析

组件简介 维护者square组织许可证类型Apache License 2.0首次发布2016 年 1 月 2 日最新发布时间2023 年 4 月 23 日GitHub Star44403GitHub Fork9197依赖包5,582依赖存储库77,217 com.squareup.okhttp3:okhttp 一个开源的 HTTP 客户端库,可以用于 Android 和 Jav…

知识图谱项目实践

目录 步骤 SpaCy Textacy——Text Analysis for Cybersecurity Networkx Dateparser 导入库 写出页面的名称 ​编辑 自然语言处理 词性标注 可能标记的完整列表 依存句法分析(Dependency Parsing,DEP) 可能的标签完整列表 实例理…

Unity 之 参数类型之值类型参数的用法

文章目录 基本数据类型结构体结构体的进一步补充 总结: 当谈论值类型参数时,我们可以从基本数据类型和结构体两个方面详细解释。值类型参数指的是以值的形式传递给函数或方法的数据,而不是引用。 基本数据类型 基本数据类型的值类型参数&…

【Java 动态数据统计图】动态数据统计思路案例(动态,排序,动态数组(重点推荐))七(129)

需求:前端根据后端的返回数据:画统计图; 说明: 1.X轴为地域,Y轴为地域出现的次数; 2. 动态展示(有地域展示,没有不展示,且高低排序) Demo案例: …

硬件SPI口扩展

在工控板设计中,经常会遇到扩展IO。具有相同的功能电路板接口相同,所以很容易采用排线方式连接到CPU主控板上,这种排线连接,我称之为总线。 现在的CPU引脚多,不扩展IO,使用模拟SPI,也可以实现&…

获取Linux内核源码

在嵌入式平台上做Linux开发的时候,我们用的kernel都是芯片厂家移植到自家平台上的,但是最初的原生Linux内核的源码是从哪里来的呢?下面我们介绍一下怎么获取原生的Linux源码。 从Linux社区获取内核kernel源码 Linux社区的官方网站是 https:…

.netcore grpc日志记录配置

一、日志记录配置概述 通过配置文件appsettings.json进行配置通过Program.cs进行配置通过环境变量进行配置客户端通过日志通道进行配置 二、实战案例 配置环境变量:Logging__LogLevel__GrpcDebug配置Appsettings.json配置Program.cs配置客户端工厂以上截图是目前为止已知的可…

基于MQTT协议的物联网网关实现远程数据采集及监控

在数字化时代的浪潮中,工业界正面临着前所未有的变革与机遇。而在这场变革中,基于MQTT协议的物联网网关崭露头角,成为连接工业设备、实现远程数据采集与监控的利器。其中,HiWoo Box作为一款出色的工业边缘网关,引领着这…

c语言每日一练(13)

前言:每日一练系列,每一期都包含5道选择题,2道编程题,博主会尽可能详细地进行讲解,令初学者也能听的清晰。每日一练系列会持续更新,上学期间将看学业情况更新。 五道选择题: 1、程序运行的结果…

9、监测数据采集物联网应用开发步骤(7)

源码将于最后一遍文章给出下载 监测数据采集物联网应用开发步骤(6) 串口(COM)通讯开发 本章节测试使用了 Configure Virtual Serial Port Driver虚拟串口工具和本人自写的串口调试工具,请自行baidu下载对应工具 在com.zxy.common.Com_Para.py中添加如下内容 #RS…

RabbitMQ 的快速使用

docker部署rabbitmq # management才有管理页面 docker pull rabbitmq:management# 新建容器并运行 docker run \-e RABBITMQ_DEFAULT_USERadmin \ -e RABBITMQ_DEFAULT_PASSadmin \ -v mq-plugins:/plugins \--name mq \--hostname mq \-p 15672:15672 \-p 5672:5672 \-itd \ra…

DNS指向别名还是IP

现在有一台服务器dbprod126,ip是172.22.100.4 现在有一个需求,需要在dns中对dbprod126建一个别名wondadb3r的记录,也就是ping wondadb3r的时候显示的是dbprod126的ip,目前有两​种方法,主要使用方法1指向别名&#xf…

SQL-basics

SQL 一些常用的查询语句用法 SQL 中的聚合函数 SQL 中的子查询 SQL 使用实例 SELECT F_NAME , L_NAME FROM EMPLOYEES WHERE ADDRESS LIKE ‘%Elgin,IL%’; SELECT F_NAME , L_NAME FROM EMPLOYEES WHERE B_DATE LIKE ‘197%’; SELECT * FROM EMPLOYEES WHERE (SALARY BET…

优化爬虫请求:如何选择合适的爬虫ip轮换策略?

在进行爬虫任务时,使用隧道爬虫ip并采用合适的轮换策略可以提高稳定性和效率。选择合适的隧道爬虫ip轮换策略可以优化您的爬虫请求过程。 1、考量目标网站特点 不同网站对于频繁请求可能有不同限制或反爬机制。 了解目标网站是否存在IP封禁、验证码等问题&#xff…

WebGIS的一些学习笔记

一、简述计算机网络的Internet 概念、网络类型分类、基本特征和功用是什么 计算机网络的Internet 概念 计算机网络是地理上分散的多台独立自主的计算机遵循约定的通讯协议,通过软、硬件互连以实现交互通信、资源共享、信息交换、协同工作以及在线处理等功能的系统…

AI聊天机器人平台Poe发布更新;自然语言理解课程概要

🦉 AI新闻 🚀 AI聊天机器人平台Poe发布更新 突破功能限制 增加企业级服务 摘要:知名问答网站Quora旗下的AI聊天机器人平台Poe发布了一系列更新,包括推出Mac应用、支持同时进行多个对话、接入Meta的Llama 2模型等功能。用户只需支…

【LeetCode】剑指 Offer <二刷>(5)

目录 题目:剑指 Offer 10- II. 青蛙跳台阶问题 - 力扣(LeetCode) 题目的接口: 解题思路: 代码: 过啦!!! 题目:剑指 Offer 11. 旋转数组的最小数字 - 力…

AD16 基础应用技巧(一些 “偏好“ 设置)

1. 修改铺铜后自动更新铺铜 AD16 铺铜 复制 自动变形 偏好设置 将【DXP】中的【参数选择】。 将【PCB Editor】中的【General】,然后勾选上【Repour Polygons After Modification】。 2. PCB直角走线处理与T型滴泪 一些没用的AD技巧——AD PCB直角走线处理与…

【大数据】Apache Iceberg 概述和源代码的构建

Apache Iceberg 概述和源代码的构建 1.数据湖的解决方案 - Iceberg1.1 Iceberg 是什么1.2 Iceberg 的 Table Format 介绍1.3 Iceberg 的核心思想1.4 Iceberg 的元数据管理1.5 Iceberg 的重要特性1.5.1 丰富的计算引擎1.5.2 灵活的文件组织形式1.5.3 优化数据入湖流程1.5.4 增量…

基于Googlenet深度学习网络的人脸身份识别matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ..................................................................... % 定义修改的范围 …