当前位置: 首页 > news >正文

阻塞式队列-生产者消费者模型

1.阻塞队列是什么

阻塞队列是一种特殊的队列. 也遵守 "先进先出" 的原则.
阻塞队列能是一种线程安全的数据结构, 并且具有以下特性:

  • 当队列满的时候, 继续入队列就会阻塞, 直到有其他线程从队列中取走元素.
  • 当队列空的时候, 继续出队列也会阻塞, 直到有其他线程往队列中插入元素.
     

阻塞队列的一个典型应用场景就是 "生产者消费者模型". 这是一种非常典型的开发模型.
 

2.生产者消费者模型

生产者消费者模型有啥用?

  • 在开发中起到服务器之间"解耦合"的效果~~
  • 在请求突然暴增的峰值中,起到"削峰填谷"的效果~~ 

 

如果A和B是直接相互调用.
此时A就得知道B的存在,B也得知道A的存在.
并且A需要知道B提供的接口是什么.B也得知道A是通过啥方式来调用的~~(耦合比较强)
如果其中一个服务挂了,另一个服务也好不到哪去~~ 

 

A不需要知道B存在,B也不需要知道A存在

双方只要认识这个阻塞队列即可~~

如果其中的一个服务挂了,并不影响另一个服务正常工作~~

 

 

如果A收到的请求突然暴增了,此时B收到的请求也会暴增!!!

如果B本身计算量已经很大了请求再次暴增,可能B就挂了~~

(每个请求处理的时候都需要分配硬件资源)

 

由阻塞队列来承担A这边的压力.
B仍然按照原有的节奏来消费队列中的数据~~ 

 

生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。
生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取.
 

1) 阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力.

比如在 "秒杀" 场景下, 服务器同一时刻可能会收到大量的支付请求. 如果直接处理这些支付请求,服务器可能扛不住(每个支付请求的处理都需要比较复杂的流程). 这个时候就可以把这些请求都放到一个阻塞队列中, 然后再由消费者线程慢慢的来处理每个支付请求.这样做可以有效进行 "削峰", 防止服务器被突然到来的一波请求直接冲垮

 2) 阻塞队列也能使生产者和消费者之间 解耦.

比如过年一家人一起包饺子. 一般都是有明确分工, 比如一个人负责擀饺子皮, 其他人负责包. 擀饺子皮的人就是 "生产者", 包饺子的人就是 "消费者".擀饺子皮的人不关心包饺子的人是谁(能包就行, 无论是手工包, 借助工具, 还是机器包), 包饺子的人也不关心擀饺子皮的人是谁(有饺子皮就行, 无论是用擀面杖擀的, 还是拿罐头瓶擀, 还是直接从超市买的)

3.标准库中的阻塞队列

在 Java 标准库中内置了阻塞队列. 如果我们需要在一些程序中使用阻塞队列, 直接使用标准库中的即可.

  • BlockingQueue 是一个接口. 真正实现的类是 LinkedBlockingQueue.
  • put 方法用于阻塞式的入队列, take 用于阻塞式的出队列.
  • BlockingQueue 也有 offer, poll, peek 等方法, 但是这些方法不带有阻塞特性.

生产者消费者模型的实现

package thread2;import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;public class Test2 {public static void main(String[] args) {BlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<>();Thread producer = new Thread(() -> {int n = 1;while (true) {try {blockingQueue.put(n);System.out.println("生产者生产了 " + n);Thread.sleep(1000);n++;} catch (InterruptedException e) {throw new RuntimeException(e);}}});producer.start();Thread customer = new Thread(() -> {while (true) {try {int n = blockingQueue.take();System.out.println("消费者消费了 " + n);Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});customer.start();}
}

阻塞队列实现(自己造轮子实现生产者消费者模型)

  • 通过 "循环队列" 的方式来实现.
  • 使用 synchronized 进行加锁控制.
  • put 插入元素的时候, 判定如果队列满了, 就进行 wait. (注意, 要在循环中进行 wait. 被唤醒时不一定队列就不满了, 因为同时可能是唤醒了多个线程).
  • take 取出元素的时候, 判定如果队列为空, 就进行 wait. (也是循环 wait)
     
package thread2;class MyBlockingQueue {private int[] items = new int[1000];private int size = 0;private int head = 0;private int tail = 0;private Object locker = new Object();public void put(int val) throws InterruptedException {synchronized (locker) {if (size == items.length) {// return;locker.wait();}items[tail] = val;tail++;if (tail >= items.length) {tail = 0;}size++;locker.notify();//唤醒take}}public Integer take() throws InterruptedException {synchronized (locker) {if (size == 0) {locker.wait();
//                return null;}int ret = items[head];head++;if (head >= items.length) {head = 0;}size--;locker.notify();//唤醒putreturn ret;}}
}public class Test1 {private static MyBlockingQueue queue = new MyBlockingQueue();public static void main(String[] args) throws InterruptedException {Thread producer = new Thread(() -> {int n = 1;while (true) {try {queue.put(n);System.out.println("生产者生产了:" + n);n++;//Thread.sleep(500);} catch (InterruptedException e) {throw new RuntimeException(e);}}});producer.start();Thread customer = new Thread(() -> {while (true) {try {int n = queue.take();System.out.println("消费者消费了 " + n);Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});customer.start();}
}



 

相关文章:

阻塞式队列-生产者消费者模型

1.阻塞队列是什么 阻塞队列是一种特殊的队列. 也遵守 "先进先出" 的原则. 阻塞队列能是一种线程安全的数据结构, 并且具有以下特性: 当队列满的时候, 继续入队列就会阻塞, 直到有其他线程从队列中取走元素.当队列空的时候, 继续出队列也会阻塞, 直到有其他线程往队…...

引导滤波code

文章目录1. 原理概述2. 实验环节2.1 验证与opencv 库函数的结果一致2.2 与 双边滤波比较2.3 引导滤波应用&#xff0c;fathering2.3 引导滤波应用&#xff0c;图像增强2.4 灰度图引导&#xff0c;和各自通道引导的效果差异2.5 不同参数设置影响3. 参考引导滤波1. 原理概述 引导…...

Leetcode.2353 设计食物评分系统

题目链接 Leetcode.2353 设计食物评分系统 Rating &#xff1a; 1782 题目描述 设计一个支持下述操作的食物评分系统&#xff1a; 修改 系统中列出的某种食物的评分。 返回系统中某一类烹饪方式下评分最高的食物。 实现 FoodRatings类&#xff1a; FoodRatings(String[] foo…...

C语言学习_DAY_2_变量的定义_输入与输出

高质量博主&#xff0c;点个关注不迷路&#x1f338;&#x1f338;&#x1f338;&#xff01; 目录 I. 变量的定义 II. 变量的赋值 III. 输出 IV. 输入 I. 变量的定义 首先&#xff0c;我们新建一个.c文件在Dev C中&#xff0c;并把之前定义好的程序框架放进去。 此时我…...

mac 安装navicat

由于各种原因发布不了链接&#xff0c;这里记录下&#xff0c;保存在了阿里云里...

RocketMQ快速入门

2.1 消息生产和消费介绍使用RocketMQ可以发送普通消息、顺序消息、事务消息&#xff0c;顺序消息能实现有序消费&#xff0c;事务消息可以解决分布式事务实现数据最终一致。RocketMQ有2种常见的消费模式,分别是DefaultMQPushConsumer和DefaultMQPullConsumer模式&#xff0c;这…...

【虚拟仿真】Unity3D实现从浏览器拉起本地exe程序并传参数

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 最近有项目需求&#xff0c;从浏览器调起来本地的exe程序&…...

Intel中断体系(1)中断与异常处理

文章目录概述中断与异常中断可屏蔽中断与不可屏蔽中断&#xff08;NMI&#xff09;异常异常分类中断与异常向量中断描述符表中断描述符中断与异常处理中断与异常处理过程堆栈切换错误码64位模式下的中断异常处理64位中断描述符64位处理器下的堆栈切换相关参考概述 中断是现代计…...

财报解读:四季度营收超预期,优步却越来越“不务正业”了

“公司第四季度的业绩表现将是强劲的”。 公布2022年第三季度财报时&#xff0c;优步的高管给出了这样的预告&#xff0c;给资本市场打了一针“强心剂”。然而有人对此表示质疑&#xff0c;后疫情时代&#xff0c;带着新模式、新车型的全新网约车公司层出不穷&#xff0c;车企…...

C语言-程序环境和预处理(14.2)

目录 预处理详解 1.预定义符号 2. #define 2.1 #define定义标识符 2.2 #define 定义宏 2.3 #define 替换规则 注意事项&#xff1a; 2.4 #和## 2.5 带副作用的宏参数 2.6 宏和函数对比 3. #undef 4. 条件编译 4.1 单分支条件编译 4.2 多分支条件编译 4.3 判断是…...

VHDL语言基础-时序逻辑电路-计数器

目录 计数器的设计&#xff1a; 计数器的作用&#xff1a; 计数器的实现&#xff1a; 1、用“”函数描述&#xff1a; 用T触发器级联构成的串行进位的二进制加法计数器的仿真波形&#xff1a; 计数器的仿真&#xff1a; 计数器的设计&#xff1a; 计数是一种最简单基本的…...

MySQL数据库07——高级条件查询

前面一章介绍了基础的一个条件的查询&#xff0c;如果多条件&#xff0c;涉及到逻辑运算&#xff0c;and or 之类的。就是高级一点的条件查询。本章来介绍复杂的条件搜索表达式。 AND运算符 AND运算符只有当两边操作数均为True时&#xff0c;最后结果才为True。人们使用AND描述…...

《Terraform 101 从入门到实践》 第四章 States状态管理

《Terraform 101 从入门到实践》这本小册在南瓜慢说官方网站和GitHub两个地方同步更新&#xff0c;书中的示例代码也是放在GitHub上&#xff0c;方便大家参考查看。 军书十二卷&#xff0c;卷卷有爷名。 为什么需要状态管理 Terraform的主要作用是管理云平台上的资源&#xff…...

数据结构之二叉树

&#x1f388;一.二叉树相关概念 1.树 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合&#xff0c;树结构通常用来存储逻辑关系为 "一对多" 的数据。例如&#xff1a; 关于树的几个重要概念&…...

上海亚商投顾:三大指数集体调整 消费板块逆市活跃

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。市场情绪三大指数今日集体调整&#xff0c;沪指全天弱势震荡&#xff0c;创业板指盘中跌超1%。旅游、食品、乳业等大消费板块…...

【2023unity游戏制作-mango的冒险】-开始画面API制作

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 收录于专栏&#xff1a;游戏制作 ⭐mango的冒险-开始画面制作⭐ 文章目录⭐mango的冒险-开始画面制作⭐&#x1f468;‍&…...

【微服务】Nacos配置管理

&#x1f6a9;本文已收录至专栏&#xff1a;微服务探索之旅 &#x1f44d;希望您能有所收获 Nacos除了可以做配置管理&#xff0c;同样可以当作注册中心来使用。 了解注册中心用法点击跳转&#x1f449;【微服务】Nacos注册中心 一.引入 当微服务部署的实例越来越多&#xff0…...

【C++】类与对象理解和学习(上)

专栏放在【C知识总结】&#xff0c;会持续更新&#xff0c;期待支持&#x1f339;类是什么&#xff1f;类是对对象进行描述的&#xff0c;是一个模型一样的东西&#xff0c;限定了类有哪些成员&#xff0c;定义出一个类并没有分配实际的内存空间来存储它&#xff08;实例化后才…...

Pyqt5小案例,界面与逻辑分离的小计算器程序

直接看下最终效果&#xff1a; 使用技术总结 使用Designer设计界面 使用pyuic5命令导出到python文件 新建逻辑处理文件&#xff0c;继承pyuic5导出的文件的类&#xff0c;在里面编写信号与槽的处理逻辑 使用Designer设计界面 要使用Designer&#xff0c;安装一个Python库即…...

leaflet加载KML文件,显示图形(方法2)

第049个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中加载KML文件,将图形显示在地图上。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果; 注意如果OpenStreetMap无法加载,请加载其他来练习 文章目录 示例效果配置方式示例源代码(共66…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上&#xff0c;对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

2.3 物理层设备

在这个视频中&#xff0c;我们要学习工作在物理层的两种网络设备&#xff0c;分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间&#xff0c;需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质&#xff0c;假设A节点要给…...

Xcode 16 集成 cocoapods 报错

基于 Xcode 16 新建工程项目&#xff0c;集成 cocoapods 执行 pod init 报错 ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchro…...