多线程应用——阻塞队列

news2025/1/30 16:34:31

阻塞队列

文章目录

  • 阻塞队列
    • 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;
        }

    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据治理-数据管理框架

DMBOK2提出的想法和概念在不同的组织中都可以应用,组织所采用的数据管理方法取决于某些关键要素,如其所处行业、所应用的数据范围、企业文化、成熟度、战略、愿景以及待解决的问题和挑战。 战略一致性模型和阿姆斯特丹模型,展示了组织管理数…

算法通关村第十二关——字符串反转问题解析

前言 字符串反转是关于字符串算法里的重要问题,虽然不是太难,但需要考虑到一些边界问题。本篇文章就对几道字符串反转题目进行分析。 1.反转字符串 力扣344题,编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数…

opencv 提取选中区域内指定hsv颜色的水印

基于《QT 插件化图像算法研究平台》做的功能插件。提取选中区域内指定hsv颜色的水印。 《QT 插件化图像算法研究平台》有个HSV COLOR PICK功能,可以很直观、方便地分析出水印 的hsv颜色,比如, 蓝色:100,180,0,255,100,255。 然后利用 opencv …

JavaScript中关于数组的小挑战

史蒂芬仍在建立他的小费计算器,使用的规则与以前一样: 如果账单价值在50到300之间,小费为账单的15%,如果价值不同,小费为20%。 编写一个函数’calcTip’,将任何账单值作为输入,并返回相应的小费…

【业务功能篇94】微服务-springcloud-springboot-认证服务-注册功能-第三方短信验证API

商城认证服务 一、搭建认证服务环境 结合我们前面介绍的商城的架构我们需要单独的搭建一个认证服务。 1.创建项目 首先创建一个SpringBoot项目&#xff0c;然后添加对应的依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"htt…

MySQL主从复制与读写分离 及其实例

目录 主从复制与读写分离 1、MySQL主从复制原理 1.1、MySQL的复制类型 1.2、MySQL主从复制的工作过程 1.3、mysq支持的复制类型 1.4、 数据流向 1.5、主从复制的工作过程 2、读写分离 2.1、什么是读写分离&#xff1f; 2.2、为什么要读写分离呢&#xff1f; 2.3、什么…

HFSS 3维曲线导入

HFSS 3维曲线导入 简介环境参考代码使用结果 简介 如图一所示&#xff0c;CST中可以通过导入和到出由任意点组成的曲线&#xff0c;但是HFSS中貌似不能导入&#xff08;如图二所示&#xff09;&#xff0c;如果我们要将matlab的产生的曲线的点的数据导入特变麻烦&#xff0c;特…

21.4 CSS 盒子模型

1. 边框样式 border-style属性: 指定元素的边框样式.常用属性值: - none: 无边框(默认值). - solid: 实线边框. - dotted: 点状边框. - dashed: 虚线边框. - double: 双线边框. - groove: 凹槽状边框. - ridge: 脊状边框. - inset: 内阴影边框. - outset: 外阴影边框.这些值可…

Loki日志系统

1、Loki是什么&#xff1f; Loki是一个开源的日志聚合系统&#xff0c;由Grafana Labs开发和维护。它旨在帮助用户收集、存储和查询大规模的日志数据&#xff0c;帮助用户更好地理解和监控他们的应用程序和系统。 Loki的设计灵感来自于Prometheus&#xff0c;它采用了类似的标…

【ROS 03】ROS通信机制进阶

上一章内容&#xff0c;主要介绍了ROS通信的实现&#xff0c;内容偏向于粗粒度的通信框架的讲解&#xff0c;没有详细介绍涉及的API&#xff0c;也没有封装代码&#xff0c;鉴于此&#xff0c;本章主要内容如下: ROS常用API介绍&#xff1b;ROS中自定义头文件与源文件的使用。…

springboot 与异步任务,定时任务,邮件任务

异步任务 在Java应用中&#xff0c;绝大多数情况下都是通过同步的方式来实现交互处理的&#xff1b;但是在处理与第三方系统交互的时候&#xff0c;容易造成响应迟缓的情况&#xff0c;之前大部分都是使用多线程来完成此类任务&#xff0c;其实&#xff0c;在Spring 3.x之后&a…

2023开学礼《乡村振兴战略下传统村落文化旅游设计》许少辉八一新书浙江师范大学图书馆

2023开学礼《乡村振兴战略下传统村落文化旅游设计》许少辉八一新书浙江师范大学图书馆

【GUI开发】用python爬YouTube博主信息,并开发成exe软件

文章目录 一、背景介绍二、代码讲解2.1 爬虫2.2 tkinter界面2.3 存日志 三、软件演示视频四、说明 一、背景介绍 你好&#xff0c;我是马哥python说&#xff0c;一名10年程序猿。 最近我用python开发了一个GUI桌面软件&#xff0c;目的是爬取相关YouTube博主的各种信息&#…

算法:图解位运算以及鸽巢原理应用

文章目录 实现原理基础位运算位图思想找最右侧数按位异或 算法思路典型例题基础位运算只出现一次的数字只出现一次的数字III 经典题型判断字符是否唯一两整数之和只出现一次的数字II消失的两个数字 鸽巢原理总结 本篇总结位运算中常见的算法题和思路&#xff0c;首先总结位运算…

边写代码边学习之TF Attention

1. 什么是Attention 注意力机制&#xff08;Attention Mechanism&#xff09;是机器学习和人工智能领域中的一个重要概念&#xff0c;用于模拟人类视觉或听觉等感知过程中的关注机制。注意力机制的目标是让模型能够在处理信息时&#xff0c;更加关注与任务相关的部分&#xff…

TDengine(2):wsl2+ubuntu20.04+TDengine安装

一、ubuntu系统下提供了三种安装TDengine的方式&#xff1a; 二、通过 apt 指令安装失败 因为是linux初学者&#xff0c;对apt 指令较为熟悉&#xff0c;因此首先使用了该方式进行安装。 wget -qO - http://repos.taosdata.com/tdengine.key | sudo apt-key add -echo "…

windows使用-设置windows的远程访问用户数量

文章目录 前言相关操作总结前言 作为IT工程师,使用服务器做相应的软件操作时常有的事。最近一段时间,我们的团队多个成员都需要远程登录到一台windows2003Server的服务器处理相应的业务。而默认情况下,Windows系统只允许一名用户远程到服务器上,这给小伙伴的工作造成一些不…

React-native环境配置与项目搭建

基础环境搭建 安装 node.js &#xff08;版本>12 ,推荐安装LTS稳定版本&#xff09; 安装 Yarn &#xff08;npm install -g yarn&#xff09; 安装 react native 脚手架 (npm install -g react-native-cli) windows 只能搭建Android 开发环境 Mac 下既能搭建Android 环境&…

斥资4亿,收购这家WLAN厂商,结果……

晚上好&#xff0c;我的网工朋友 不少朋友可能有隐形&#xff0c;2019年的时候&#xff0c;Juniper花费4.05亿美元&#xff0c;收购WiFi初创公司Mist Systems。 Mist Systems是一家买无线产品起家的公司&#xff0c;由前思科高管创建的。主打的产品是“AI-Driven WLAN”&…

linux安装firefox

1.下载对应包 https://www.mozilla.org/en-US/firefox/all/#product-desktop-release 2. 挂载桌面链接(如果/usr/bin/firefox下有的话,先删除) ln -s /opt/firefox/firefox /usr/bin/firefox 3.执行以下命令&#xff0c;即可启动Firefox客户端&#xff1a; firefox