阻塞队列、生产者消费者模型、阻塞队列的模拟实现等干货

文章目录

  • 💐生产者消费者模型
  • 💐模拟实现阻塞队列
    • 💡注意点一
    • 💡注意点二

阻塞队列是一种“特殊”的数据结构,但是也遵循队列的“先进先出”特性,它的特殊在于:

阻塞队列的两个特性:

1、阻塞队列是线程安全的

2、带有阻塞特性:

​ a.向队列中添加元素时,如果队列满了,就会阻塞等待,直到其他线程从队列中取走元素时才会解除等待

​ b.从队列中向外拿元素时,如果队列为空,就会阻塞等待,直到其他线程向队列中添加元素后,才会解除等待

阻塞队列的最大作用就是可以用来实现“生产者消费者模型”;

💐生产者消费者模型

什么是生产者消费者模型?

比如,在过年时包饺子,妈妈负责擀饺子皮,我负责包饺子,妈妈会把擀好的饺子皮放在板子上,此时,我就可以拿饺子皮开始包饺子,当板子上没有饺子皮时,我就要等妈妈擀,如果当板子上的饺子皮满了的时候,妈妈就会停止擀饺子皮,等到板子上有位置了以后,才会继续擀,所以,妈妈就相当于是一个生产者,我就相当于是一个消费者,放饺子皮的板子就相当于是一个阻塞队列。

1、生产者消费者模型可以解决强耦合问题:

什么是强耦合:

例如,有一个简单的分布式系统,客户端向服务器机房发送一个要求后等待服务器响应,但是,这个要求可能需要两个服务器联合进行处理,假设,有一个A服务器和B服务器,A服务器可能需要B服务器的响应后再进行后序的处理,但是呢,如果因为B服务器挂了,那么就会导致A服务器也会挂,所以这种联系较紧密的强耦合模块就很容易出现问题;

在这里插入图片描述

针对上述情况,就可以引入一个阻塞队列来解决:

将阻塞队列也封装成一个单独的服务器程序,让A服务器直接和这个阻塞队列进行交互,让B服务器也直接和阻塞队列进行交互,不管B到底会不会出错,也都不会影响到A,A都只会和阻塞队列进行交互,就算以后再增加多个服务器的话,也就只是和阻塞队列进行交互,A也不必进行修改,这样就降低了耦合性👇

在这里插入图片描述

2、削峰填谷

”峰“的意思是:短时间内,请求量比较多

”谷”的意思是:请求量比较少

如果在没有引入阻塞队列的情况下(如上图一),如果客户端这边的请求量比较大,那么,不管A接受多少请求量,都会直接发给B,A和B所要承受的压力是一样的,但是,每个服务器都是不一样的,可能就会出现,对于这个并发量,A服务器可以承受,B服务器就承受不了;

对于这种情况就可以用生产者消费者模型解决:

和图二一样,给A发过去的请求量,并不直接发给B,而是发队列,B仍然按照他自己的速度处理请求,举个例子:假如,A和B每秒钟可以处理1000条请求,但是,出现了极端情况,A每秒处理了3000条请求,但是呢,B仍然会继续按照每秒处理1000条请求,这样,请求就会在队列中积压,如果队列满了的话,A向队列中发送请求就发生阻塞,直到B从队列中取出请求,使队列出现空余空间后,A再继续发出请求,就这样,一来一回,虽然可能响应有点慢了,但是总比把B服务器搞挂了好;而后续A服务器发出的请求量少了以后,B服务器就可以慢慢的处理完这些积压的请求;

有了这样的机制后,就可以保证在突发情况突然来临时,服务器仍然能够正常运行

💐模拟实现阻塞队列

class MyBlockingQueue<T> {private Object[] element = new Object[5];//为了避免内存可见性问题,加上一个volatileprivate volatile int head;//记录当前要弹出元素的位置private volatile int tail;//记录当前要添加元素的位置private  volatile int size;//向队列中添加一个元素public void put(T elem) {//加锁synchronized(this) {//判断队列是否满了while(size == element.length) {//阻塞等待try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}//没满情况element[tail] = elem;tail++;//判断tail是否是数组最后一个元素if(tail == element.length){tail = 0;}size++;this.notify();}}//弹出队列中的一个元素public T take() {synchronized (this) {//判断队列是否为空while(size == 0) {//阻塞等待try {this.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}//不为空情况T ret = (T)element[head];head++;if(head == element.length) {head = 0;}size--;this.notify();return ret;}}}

💡注意点一

在这里插入图片描述

put() 方法里面的wait需要take()里面的notify唤醒,take()方法里面的wait需要put() 里面的notify唤醒,因为,当在put里面调用wait后,就会处于阻塞等待,就算是继续调用put,仍然会阻塞等待,必须调用take里面的notify后,才后解除等待,take也同理,所以不可能出现方法内调用notify解除方法自己的wait这中情况;

💡注意点二

在这里为什么要使用while循环判断?

在这里插入图片描述

wait被唤醒的方式除了notify外,还有一种方式就是,如果在其他线程中调用interupt方法可能会中断wait的等待,就如上面代码一样,如果一旦调用了interupt方法,那么wait就会被唤醒,被唤醒之后,代码并没有退出,这时候,如果数组仍然是满的话,那么就会出现bug,此时的tail指向的还是一个有效元素,这个有效元素就会被修改,并且size++,size就超过了数组的长度,所以,利用while语句,一旦wait被唤醒,那么就再次进行一下判断,如果数组是满的,仍然继续等待,反之向下执行,take也同理;

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习基于 JavaScript 语言 的计算机界三大神书”之一 ——SICP

如何阅读“计算机界三大神书”之一 ——SICP 《计算机程序的构造和解释》&#xff08;Structure and Interpretation of Computer Programs&#xff0c;简记为SICP&#xff09;是MIT的基础课教材&#xff0c;出版后引起计算机教育界的广泛关注&#xff0c;对推动全世界大学计算…

C switch 语句

一个 switch 语句允许测试一个变量等于多个值时的情况。每个值称为一个 case&#xff0c;且被测试的变量会对每个 switch case 进行检查。 语法 C 语言中 switch 语句的语法&#xff1a; switch(expression){case constant-expression :statement(s);break; /* 可选的 */ca…

【小白友好】LeetCode 打家劫舍 III

https://leetcode.cn/problems/house-robber-iii/description/ 前言 建议还是先看看动态规划的基础题再看这个。动态规划是不刷题&#xff0c;自己100%想不出来的。 基础题&#xff1a; 最大子数组和乘积最大子数组最长递增子序列 最大升序子数组和 小白想法 现在我们想遍…

前端语义化标签及实例

常用的语义化标签的以下几种&#xff1a; header、nav、article、section、aside、footer、abbr、dfn、address、del、ins、pre、meter、progress <header> 定义文章的页眉信息 <header><h1>我的网站标题</h1><nav><ul><li><a …

[GYCTF2020]EasyThinking --不会编程的崽

看标题就知道&#xff0c;这大概率是关于thinkphp的题目。先尝试错误目录使其报错查看版本号 thinkphp v6.0.0&#xff0c;在网上搜索一下&#xff0c;这个版本有一个任意文件上传漏洞。参考以下文章。 https://blog.csdn.net/god_zzZ/article/details/104275241 先注册一个账…

【Android】位置修改相关

获取位置服务总开关状态 //获取LOCATION_MODE值&#xff0c;但adb状态下无法获取 //0为关闭&#xff0c;1 gps、2 network、3 高精度等 int state Settings.Secure.getInt(mContext.getContentResolver(),Settings.Secure.LOCATION_MODE,Settings.Secure.LOCATION_MODE_HIGH_…

three.js可以对3D模型做什么操作和交互,这里告诉你。

Three.js 提供了多种交互功能&#xff0c;可以对 3D 模型进行各种操作和交互。以下是一些常见的交互功能&#xff1a; 鼠标交互 通过鼠标事件&#xff0c;可以实现模型的拖拽、旋转、缩放等操作。例如&#xff0c;可以通过鼠标拖拽来改变模型的位置或角度。 触摸交互 对于支…

PackagesNotFoundError:学习利用报错信息找到解决方法

反思&#xff1a;之前看到报错经常是直接复制报错信息去网上搜&#xff0c;但很多情况下报错信息里其实就给出了解决方案 报错信息&#xff1a; Collecting package metadata (current_repodata.json): done Solving environment: unsuccessful initial attempt using frozen …

MySQL 篇-深入了解多表设计、多表查询

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 多表设计概述 1.1 多表设计 - 一对多 1.2 多表设计 - 一对一 1.3 多表设计 - 多对多 2.0 多表查询概述 2.1 多表查询 - 内连接 2.2 多表查询 - 外连接 2.3 多表查…

cetos7 Docker 安装 gitlab

一、gitlab 简单介绍和安装要求 官方文档&#xff1a;https://docs.gitlab.cn/jh/install/docker.html 1.1、gitlab 介绍 gitLab 是一个用于代码仓库管理系统的开源项目&#xff0c;使用git作为代码管理工具&#xff0c;并在此基础上搭建起来的Web服务平台&#xff0c;通过该平…

【C语言】指针初阶2.0版本

这篇博文我们来继续学习指针的其他内容 指针2.0 传值调用与传址调用传值调用传址调用 一维数组与指针理解数组名使用指针深入理解一维数组 二级指针指针数组二维数组与指针 传值调用与传址调用 在开始之前&#xff0c;我们需要先了解这个概念&#xff0c;后面才能够正常的学习…

Material UI 5 学习01-按钮组件

Material UI 5 学习01-按钮组件 一、安装Material UI二、 组件1、Button组件1、基础按钮2、variant属性3、禁用按钮4、可跳转的按钮5、disableElevation属性6、按钮的点击事件onClick 2、Button按钮的颜色和尺寸1、Button按钮的颜色2、按钮自定义颜色3、Button按钮的尺寸 3、图…

vulhub中ThinkPHP5 SQL注入漏洞 敏感信息泄露

漏洞原理 传入的某参数在绑定编译指令的时候又没有安全处理&#xff0c;预编译的时候导致SQL异常报错。然而thinkphp5默认开启debug模式&#xff0c;在漏洞环境下构造错误的SQL语法会泄漏数据库账户和密码 启动后&#xff0c;访问http://your-ip/index.php?ids[]1&ids[]2…

nodejs安装教程(及过程中的易错)

nodejs&#xff1a;Nodejs 是基于 Chrome 的 V8 引擎开发的一个 C 程序&#xff0c;目的是提供一个 JS 的运行环境。 npm&#xff1a;npm 是 Node Package Manager 的缩写&#xff0c;意思是 Node 的包管理系统&#xff0c;是最大的软件包仓库 下载nodejs 首先我们需要在node…

智慧城市中的数据力量:大数据与AI的应用

目录 一、引言 二、大数据与AI技术的融合 三、大数据与AI在智慧城市中的应用 1、智慧交通 2、智慧环保 3、智慧公共安全 4、智慧公共服务 四、大数据与AI在智慧城市中的价值 1、提高城市管理的效率和水平 2、优化城市资源的配置和利用 3、提升市民的生活质量和幸福感…

去除PDF论文行号的完美解决方案

去除PDF论文行号的完美解决方案 1. 遇到的问题 我想去除论文的行号&#xff0c;但是使用网上的Adobe Acrobat裁剪保存后 如何去掉pdf的行编号&#xff1f; - 知乎 (zhihu.com) 翻译时依然会出现行号&#xff0c;或者是转成word&#xff0c;这样就大大损失了格式&#xff0c…

C语言结构体的大小,结构体内存对齐

1. 结构体的大小 在自己正真了解过之前&#xff0c;一直认为结构体的大小就是结构体内部成员大小的总和。 但当你去尝试打印结构体的大小时&#xff0c;会发现事实并非如此&#xff0c;也不会像你想的那样简单。 #include <stdio.h>struct S1 {char c1;char c2;int i;…

springcloud:3.7测试线程池服务隔离

服务提供者【test-provider8001】 Openfeign远程调用服务提供者搭建 文章地址http://t.csdnimg.cn/06iz8 相关接口 测试远程调用&#xff1a;http://localhost:8001/payment/index 服务消费者【test-consumer-resilience4j8004】 Openfeign远程调用消费者搭建 文章地址http://t…

人工智能指数报告2023

人工智能指数报告2023 主要要点第 1 章 研究与开发第 2 章 技术性能第 3 章 人工智能技术伦理第 4 章 经济第 5 章 教育第 6 章 政策与治理第 7 章 多样性第 8 章 舆论 人工智能指数是斯坦福大学以人为本的人工智能研究所&#xff08;HAI&#xff09;的一项独立倡议&#xff0c…

如何编写自动化测试用例?

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 自动化测试脚本 什么是自动化测试&#xff1f; 自动化测试是验…