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

阻塞队列的实现(线程案例)

一.什么是阻塞队列?

1.如果对于一个满的队列,还要把元素入队列,此时这个队列就会阻塞等待,一直阻塞到这个队列不满为止,从而把这个元素入队列

2.如果对于一个空的队列,还要从队列拿出元素,此时这个队列就会阻塞等待,一直阻塞到这个队列不空为止,从而把这个元素拿出队列

二.阻塞队列有什么作用:

1.解耦合作用

什么是耦合度:

耦合度高:就是模块之间联系比较紧密,彼此之间互相影响

耦合度低:就模块之间联系没有那么紧密,也就是模块之间影响小

此时引入阻塞队列,就可以有效降低模块之间的耦合度,起到了解耦合的作用!!

看图👇


2.削峰填谷作用


三.代码的实现

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;public class ThreadDemo11 {public static void main(String[] args) throws InterruptedException {BlockingQueue<String> queue = new ArrayBlockingQueue<>(100);queue.put("666");String s=queue.take();System.out.println(s);s=queue.take();System.out.println(s);}
}

此时阻塞等待👇

四.自己模拟实现

//实现阻塞队列
class MyBlockingQueue{//这个是模拟实现队列private String[] elems = null;private int head = 0;private int tail = 0;private int size = 0;private Object locker = new Object();//实现构造方法👇public MyBlockingQueue(int capacity){elems = new String[capacity];}//放进元素public void put (String elem) throws InterruptedException {synchronized (locker){//超出队列长度!//使用while循环,是防止线程唤醒后只判断一次,让被唤醒的线程再判断一次while(size >= elems.length){locker.wait();}//往这里加元素!!!elems[tail] = elem;tail++;//这里面是循环队列,可使这块空间能够被循环利用!,所以需要tail = 0;if(tail == elems.length){tail = 0;}size++;locker.notify();}}//拿出元素public String take() throws InterruptedException {String elem = null;//队列里面没有元素,阻塞等待synchronized (locker){while(size == 0){locker.wait();}//拿出一个元素elem = elems[head];head++;if(head == elems.length){head = 0;}size--;locker.notify();}return elem;}}public class ThreadDemo10 {public static void main(String[] args) {MyBlockingQueue myBlockingQueue = new MyBlockingQueue(1000);//创建两个线程实现生产者和消费者模型Thread t1 =new Thread(()->{int n = 1;while(true){try {myBlockingQueue.put(n+"");System.out.println("生产元素"+n);n++;} catch (InterruptedException e) {throw new RuntimeException(e);}}});Thread t2 = new Thread(()->{while(true){try {String n = myBlockingQueue.take();System.out.println("消费元素"+n);Thread.sleep(500);} catch (InterruptedException e) {throw new RuntimeException(e);}}});//线程的启动!!t1.start();t2.start();}
}

代码中的一些问题

是否能够把里面这个while改成if👇

   if(size >= elems.length){locker.wait();}
答案是不能的,为什么呢

假设这个队列的容量是1,且此时容量已满。假设有3个线程t1,t2、t3.

t1和t2都调用put(),此时t1线程进入wait()状态,由于wait()状态,t1线程释放了锁。然后

t2也进入了锁里面,进入wait()状态,也释放了锁。

t3线程执行take(),从线程中拿出了一个元素,然后进行notify(),随机唤醒了其中一个线程,假设唤醒了t1线程,t1线程把一个元素放进了队列,此时队列满了,然后notify(),唤醒了t2

线程,由于if操作已经执行过了,所以它要把元素放进队列,由于队列容量为1,所以t2无法把元素放进队列中,此时代码便出现了问题。

由此可见,使用while()可以使线程唤醒之后,再判断一次条件,进而避免了线程安全的问题!


五.生产者-消费者模型

这就可以使用阻塞队列来完成

此时这个生产元素的速度要比消费元素速度要快,所以队列会先满了,然后阻塞等待,最后就是消费一个元素,生产一个元素,趋于平衡。

那么就会有人说,队列的容量不是1000,为什么会出现1001

原因就在于:线程的调度是不确定的。

当生产元素1000已经达到了队列的容量,这是毋庸置疑的。然后线程进行消费元素,然后notify(),唤醒了生产元素的线程,此时这个消费元素还没有打印,然后这个生产元素的线程打印了生产元素1001。

相关文章:

阻塞队列的实现(线程案例)

一.什么是阻塞队列&#xff1f; 1.如果对于一个满的队列&#xff0c;还要把元素入队列&#xff0c;此时这个队列就会阻塞等待&#xff0c;一直阻塞到这个队列不满为止&#xff0c;从而把这个元素入队列&#xff01; 2.如果对于一个空的队列&#xff0c;还要从队列拿出元素&…...

http status是什么?常见的http状态码指的是什么意思?

HTTP 状态码 HTTP 状态码&#xff08;HTTP Status Code&#xff09;是服务器在响应客户端请求时返回的一个三位数字代码&#xff0c;用于表示请求的处理结果。HTTP 状态码是 HTTP 协议的一部分&#xff0c;帮助客户端&#xff08;如浏览器或应用程序&#xff09;了解请求是否成…...

react组件分离,降低耦合

分离前 分离后...

【AI】AI白日梦+ChatGPT 三分钟生成爆款短视频

引言 随着人工智能&#xff08;AI&#xff09;技术的快速发展&#xff0c;AI在各个领域都展现出了强大的应用潜力。其中&#xff0c;自然语言处理技术的进步使得智能对话系统得以实现&#xff0c;而ChatGPT作为其中的代表之一&#xff0c;具有自动生成文本的能力&#xff0c;为…...

MYSQL的安装教程

mysql安装分为&#xff1a;普通安装和压缩包安装 压缩包安装很多会存在安装失败的情况&#xff0c;所以我这里就用了普通安装 一、官网下载安装包 www.mysql.com 点击DOWNLOADS&#xff1a; 进入社区版本下载&#xff1a; 点击最下面一行进行下载&#xff1a; 选择第二个离…...

深入解析 C# 中的泛型:概念、用法与最佳实践

C# 中的 泛型&#xff08;Generics&#xff09; 是一种强大的编程特性&#xff0c;允许开发者在不预先指定具体数据类型的情况下编写代码。通过泛型&#xff0c;C# 能够让我们编写更灵活、可重用、类型安全且性能优良的代码。泛型广泛应用于类、方法、接口、委托、集合等多个方…...

NUMA架构介绍

NUMA 架构详解 NUMA&#xff08;Non-Uniform Memory Access&#xff0c;非统一内存访问&#xff09; 是一种多处理器系统的内存设计架构&#xff0c;旨在解决多处理器系统中内存访问延迟不一致的问题。与传统的 UMA&#xff08;Uniform Memory Access&#xff0c;统一内存访问…...

数据安全VS创作自由:ChatGPT与国产AI工具隐私管理对比——论文党程序员必看的避坑指南

文章目录 数据安全VS创作自由&#xff1a;ChatGPT与国产AI工具隐私管理对比——论文党程序员必看的避坑指南ChatGPTKimi腾讯元宝DeepSeek 数据安全VS创作自由&#xff1a;ChatGPT与国产AI工具隐私管理对比——论文党程序员必看的避坑指南 产品隐私设置操作路径隐私协议ChatGPT…...

python爬虫:python中使用多进程、多线程和协程对比和采集实践

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 1. 多进程爬虫1.1 python多进程样例1.2 实现多进程爬虫2. 多线程爬虫2.1 python多线程样例2.2 实现多线程爬虫3. 协程爬虫3.1 python协程样例3.2 实现协程爬虫在网络爬虫中,为了提高抓取效率,常常需要使用多进程、多线…...

《OpenCV》—— dlib库

文章目录 dlib库是什么&#xff1f;OpenCV库与dlib库对比dlib库安装dlib——人脸应用实例——人脸检测dlib——人脸应用实例——人脸关键点定位dlib——人脸应用实例——人脸轮廓绘制 dlib库是什么&#xff1f; OpenCV库与dlib库对比 dlib库安装 dlib——人脸应用实例——人脸检…...

Linux搜索---find

find搜索 find 命令的核心功能是在指定的目录路径下&#xff0c;递归地搜索文件和目录&#xff0c;并且可以根据多种条件对搜索结果进行筛选&#xff0c;还能对符合条件的文件和目录执行特定操作。 一、基础语法结构 find [起始目录] [匹配条件] [执行操作] # 基本示例 find…...

python之爬虫入门实例

链家二手房数据抓取与Excel存储 目录 开发环境准备爬虫流程分析核心代码实现关键命令详解进阶优化方案注意事项与扩展 一、开发环境准备 1.1 必要组件安装 # 安装核心库 pip install requests beautifulsoup4 openpyxl pandas# 各库作用说明&#xff1a; - requests&#x…...

Blender常用快捷键的汇总

一、基础操作 全选/取消全选&#xff1a;A&#xff08;全选&#xff09;、AA&#xff08;连续按两次A取消全选&#xff09;复制物体&#xff1a;Shift D&#xff08;复制后需点击确认位置&#xff09;移动物体&#xff1a;G&#xff08;按X/Y/Z可约束轴向移动&#xff09;旋转…...

鸿蒙启动页开发

鸿蒙启动页开发 1.1 更改应用名称和图标 1.更改应用图标 找到moudle.json5文件&#xff0c;找到应用启动的EntryAbility下面的icon,将原来的图标改成自己设置的即可 2.更改应用名称 3.效果展示 2.1 广告页面开发 3.1 详细介绍 3.1.1 启动页面 import { PrivacyDialog } fr…...

Unity 文字高度自适应

期望 文字有字号限制&#xff0c;输入文字文字后先判断高度是否适用于限制字号&#xff0c;若处于最小字号时高度任不适用&#xff0c;则调整RectTransform 的高度。 核心代码 每次输入文字时先将字号设定为原始字号。 comp.fontSize fontSize; comp.text content; 拓展T…...

Teaching Small Language Models Reasoning throughCounterfactual Distillation

2024.emnlp-main.333.pdfhttps://aclanthology.org/2024.emnlp-main.333.pdf 1.概述 大型语言模型(LLM),如GPT-3,在各种下游任务中表现出色,包括通过链式思维(CoT)进行问题解答。CoT鼓励模型在解决问题时生成中间推理步骤。尽管LLM取得了成功,但由于模型大小的限制,其…...

快速开始React开发(一)

快速开始React开发&#xff08;一&#xff09; React是一个JavaScript库&#xff0c;用于构建交互式网站&#xff0c;并且能够快捷创建SPA&#xff08;Single Page App&#xff09;&#xff0c;其组件化的思想也是被一再传播&#xff0c;无论是普通的Web网站还是嵌入移动端交互…...

2025最新Transformer模型及深度学习前沿技术应用

第一章、注意力&#xff08;Attention&#xff09;机制 1、注意力机制的背景和动机&#xff08;为什么需要注意力机制&#xff1f;注意力机制的起源和发展里程碑&#xff09;。 2、注意力机制的基本原理&#xff08;什么是注意力机制&#xff1f;注意力机制的数学表达与基本公…...

极狐GitLab 正式发布安全版本17.9.1、17.8.4、17.7.6

本分分享极狐GitLab 补丁版本 17.9.1、17.8.4、17.7.6 的详细内容。这几个版本包含重要的缺陷和安全修复代码&#xff0c;我们强烈建议所有私有化部署用户应该立即升级到上述的某一个版本。对于极狐GitLab SaaS&#xff0c;技术团队已经进行了升级&#xff0c;无需用户采取任何…...

[环境搭建篇] Windows 环境下如何安装Docker工具

Windows 环境下如何安装Docker工具 1. 检查系统要求2. 启用WSL 2和虚拟化步骤一&#xff1a;启用WSL步骤二&#xff1a;启用虚拟化&#xff08;Hyper-V&#xff09;步骤三&#xff1a;安装WSL 2内核 3. 安装Docker Desktop4. 配置Docker5. 家庭版用户替代方案6. 常见问题解决问…...

Qt QFile与QTextStream高效文本处理实战指南

1. Qt文件处理基础与QFile核心用法 在Qt开发中&#xff0c;文件操作是每个开发者必须掌握的基础技能。无论是处理配置文件、记录日志还是数据持久化&#xff0c;都离不开对文件的读写操作。QFile作为Qt框架中专门用于文件操作的类&#xff0c;提供了跨平台的文件处理能力&…...

SRS服务器从编译到实战:Ubuntu环境下的RTMP/WebRTC全协议测试

SRS服务器从编译到实战&#xff1a;Ubuntu环境下的RTMP/WebRTC全协议测试 在流媒体技术快速发展的今天&#xff0c;构建一个高效、稳定的视频服务器成为许多开发者和企业的核心需求。SRS(Simple Realtime Server)作为一款开源的实时视频服务器&#xff0c;凭借其对多种流媒体协…...

Java开源项目—上门家政系统源码

首页与服务展示LBS定位服务&#xff1a; 系统自动定位用户所在城市&#xff08;如“广州”&#xff09;&#xff0c;并根据地理位置推荐附近的服务资源&#xff0c;确保服务的时效性。多品类服务入口&#xff1a; 首页采用图标矩阵展示&#xff0c;涵盖家庭保洁、上门维修、家电…...

【2026唯一认证流式部署标准】:FastAPI 2.0 + Uvicorn 24.8 + ASGI 4.0协同流控协议详解(含OpenTelemetry追踪模板)

第一章&#xff1a;FastAPI 2.0 异步 AI 流式响应的范式演进与2026标准定位FastAPI 2.0 将原生支持全链路异步流式响应&#xff08;StreamingResponse&#xff09;与 Server-Sent Events&#xff08;SSE&#xff09;语义融合&#xff0c;标志着 AI 应用后端从“请求-响应”单次…...

从‘localhost:8080’到‘dev.myapp.com’:给本地服务绑个‘正经’域名的三种方法(Nginx/Docker/系统Hosts)

从‘localhost:8080’到‘dev.myapp.com’&#xff1a;本地服务域名绑定的实战指南 每次调试前端页面时&#xff0c;在浏览器地址栏反复输入localhost:3000或127.0.0.1:8080&#xff0c;这种体验总让人感觉像是在用临时解决方案应付正式开发需求。想象一下&#xff0c;当你的团…...

WPF Chart控件实战:构建高性能实时数据监控曲线

1. WPF Chart控件基础入门 第一次接触WPF Chart控件时&#xff0c;我也被它强大的功能震撼到了。这个控件就像是一个神奇的画板&#xff0c;能够将枯燥的数据变成直观的曲线图。在工业监控系统中&#xff0c;我们经常需要实时显示温度、压力等参数的变化趋势&#xff0c;这时候…...

Obsidian插件终极汉化指南:obsidian-i18n让英文插件秒变中文界面

Obsidian插件终极汉化指南&#xff1a;obsidian-i18n让英文插件秒变中文界面 【免费下载链接】obsidian-i18n 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-i18n 你是否因为Obsidian插件的英文界面而头疼&#xff1f;面对"Backlink"、"Graph …...

Wan2.2-I2V-A14B在微信小程序开发中的应用:实时图片转视频功能实现

Wan2.2-I2V-A14B在微信小程序开发中的应用&#xff1a;实时图片转视频功能实现 1. 引言 "一张照片能变成视频吗&#xff1f;"这是很多社交类小程序用户常有的疑问。想象一下&#xff0c;用户在电商小程序上传商品图片后&#xff0c;系统自动生成一段展示视频&#…...

告别Windows AI困扰:RemoveWindowsAI工具全方位解决方案

告别Windows AI困扰&#xff1a;RemoveWindowsAI工具全方位解决方案 【免费下载链接】RemoveWindowsAI Force Remove Copilot and Recall in Windows 项目地址: https://gitcode.com/GitHub_Trending/re/RemoveWindowsAI 在数字时代的隐私保卫战中&#xff0c;Windows系…...

出国旅行手机没信号?Nrfr免Root工具一键解锁全球网络

出国旅行手机没信号&#xff1f;Nrfr免Root工具一键解锁全球网络 【免费下载链接】Nrfr &#x1f30d; 免 Root 的 SIM 卡国家码修改工具 | 解决国际漫游时的兼容性问题&#xff0c;帮助使用海外 SIM 卡获得更好的本地化体验&#xff0c;解锁运营商限制&#xff0c;突破区域限制…...