多线程---阻塞队列+生产者消费者模型

news/2024/5/5 1:48:18/文章来源:https://blog.csdn.net/weixin_62976968/article/details/134105398

文章目录

  • 阻塞队列
    • 自己实现一个阻塞队列(三步)
    • 标准库中的阻塞队列
    • 使用阻塞队列的优势
  • 生产者消费者模型

阻塞队列

队列(Queue)是我们熟悉的一个数据结构,它是“先进先出”的。但是并不是所有的队列都是“先进先出”的,比如:
优先级队列(PriorityQueue):基于自己的比较规则,拿出相应的值。
消息队列(MQ):在队列中引入一个“类型”,出队列的时候会指定某个类型的元素先出。

而我们今天学习的阻塞队列,它是一个“先进先出”的队列,但又有一些其他特点:

  1. 线程安全的。
  2. 带有阻塞功能:
    如果队列满,继续入队列,入队列操作就会阻塞,直到队列不满,入队列操作才能完成。
    如果队列空,继续出队列,出队列操作就会阻塞,直到队列不空,出队列操作才能完成。

自己实现一个阻塞队列(三步)

  • 实现基本队列
class MyBlockingQueue{public int[] items = new int[100];public int head = 0;public int tail = 0;public int size = 0;//入队列public void put ( int key)  {// 插入操作items[tail] = key;tail++;if (tail >= items.length) {tail = 0;}size++;}//出队列public Integer take()  {// 删除操作int ret = items[head];head++;if (head >= items.length) {head = 0;}size--;return ret;}
}
  • 保证线程安全
class MyBlockingQueue{public int[] items = new int[100];public int head = 0;public int tail = 0;public int size = 0;//入队列public void put ( int key)  {synchronized (this) {// 插入操作items[tail] = key;tail++;if (tail >= items.length) {tail = 0;}size++;}}//出队列public Integer take()  {synchronized (this) {// 删除操作int ret = items[head];head++;if (head >= items.length) {head = 0;}size--;return ret;}}
}
  • 实现阻塞功能
class MyBlockingQueue{public int[] items = new int[100];public int head = 0;public int tail = 0;public int size = 0;//入队列public void put ( int key) throws InterruptedException {synchronized (this) {//当wait被唤醒之后 size还有可能为满 所以不能一唤醒了就直接去使用 得再次判断条件是否满足// 比如:1.抛出异常  2. 三个线程同时执行 其中两个线程竞争锁 没竞争到锁的线程被唤醒之后size还为空while(size >= items.length){this.wait();}//判断队列是否为满  满了不能插入 就阻塞
//            if (size >= items.length){
//                this.wait();
//            }// 插入操作items[tail] = key;tail++;if (tail >= items.length) {tail = 0;}size++;this.notify();}}//出队列public Integer take() throws InterruptedException {synchronized (this) {//当wait被唤醒之后 size还有可能为空 所以不能一唤醒了就直接去使用 得再次判断条件是否满足while(size <= 0){this.wait();}//判断队列是否为空 空了不能删除 就阻塞
//            if (size <= 0){
//                this.wait();
//            }// 删除操作int ret = items[head];head++;if (head >= items.length) {head = 0;}size--;this.notify();return ret;}}
}

标准库中的阻塞队列

    //标准库的阻塞队列public static void main(String[] args) throws InterruptedException {BlockingQueue<Integer> blockingQueue = new LinkedBlockingDeque<>(2);//带有阻塞功能的入队列blockingQueue.put(1);blockingQueue.put(2);blockingQueue.take();blockingQueue.put(3);//带有阻塞功能的出队列System.out.println(blockingQueue.take());System.out.println(blockingQueue.take());System.out.println(blockingQueue.take());blockingQueue.put(4);System.out.println(blockingQueue.take());blockingQueue.put(4);}

使用阻塞队列的优势

  • 有利于代码解耦合

在这里插入图片描述
在这里插入图片描述

  • 削峰填谷

在服务器A流量激增的情况下,通过阻塞队列能够进行限流。使服务器B、C、D能够不受干扰、平稳运行。

生产者消费者模型

生产者消费者模型:描述的是多线程协同工作的一种方式。借助阻塞队列实现。

	//生产者-消费者模型public static void main(String[] args) {MyBlockingQueue myBlockingQueue = new MyBlockingQueue();Thread thread = new Thread(() -> {int n = 1;while (true){try {myBlockingQueue.put(n);} catch (InterruptedException e) {e.printStackTrace();}n++;}});Thread thread1 = new Thread(() -> {while (true){try {System.out.println(myBlockingQueue.take());} catch (InterruptedException e) {e.printStackTrace();}try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}});thread.start();thread1.start();}

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

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

相关文章

动静分离技术

一、HAproxy 动静分离 1、概念&#xff1a; HAproxy 动静分离技术是一种用于优化 Web 服务器性能和提高用户体验的策略&#xff0c;它通过将动态内容和静态内容分别路由到不同的后端服务器来实现&#xff0c;减轻服务器负载&#xff0c;提高网站的响应速度。 动态内容包括由…

maven子模块无法导入jar包问题

明明本地仓库有jar包 maven子模块无法导入jar包&#xff0c;然后放到父项目的pom.xml则可以导入 可以试试更新仓库后&#xff0c;引入成功

【Linux】多路IO复用技术①——select详解如何使用select在本地主机实现简易的一对多服务器(附图解与代码实现)

这一篇的篇幅可能有点长&#xff0c;但真心希望大家能够静下心来看完&#xff0c;相信一定会有不小的收获。那么话不多说&#xff0c;我们这就开始啦&#xff01;&#xff01;&#xff01; 目录 一对一服务器中的BUG 如何实现简易的一对多服务器 实现简易一对多服务器的大体…

软考下午第一题 案列分析

期待分值 10&#xff0c;前三问12左右分&#xff0c;最后一题2、3分左右&#xff0c;重点在于拿下前面三题。 小心谨慎&#xff0c;不要大意。 数据流图 外部系统 数据存储 加工&#xff08;&#xff09;process 数据流 第二小题 说明给出存储名称&#xff0c;就使用该名称&…

最短路径:迪杰斯特拉算法

简介 英文名Dijkstra 作用&#xff1a;找到路中指定起点到指定终点的带权最短路径 核心步骤 1&#xff09;确定起点&#xff0c;终点 2&#xff09;从未走过的点中选取从起点到权值最小点作为中心点 3&#xff09;如果满足 起点到中心点权值 中心点到指定其他点的权值 < 起…

STM32单片机智能小车一PWM方式实现小车调速和转向

目录 1. 电机模块开发 2. 让小车动起来 3. 串口控制小车方向 4. 如何进行小车PWM调速 5. PWM方式实现小车转向 1. 电机模块开发 L9110s概述 接通VCC&#xff0c;GND 模块电源指示灯亮&#xff0c; 以下资料来源官方&#xff0c;具体根据实际调试 IA1输入高电平&#xff…

BUUCTF qr 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 这是一个二维码&#xff0c;谁用谁知道&#xff01; 密文&#xff1a; 下载附件&#xff0c;得到一张二维码图片。 解题思路&#xff1a; 1、这是一道签到题&#xff0c;扫描二维码得到flag。 flag&#xff1a;…

外汇天眼:在2023年Expo上探索金融科技的未来!

从2020年初至2022年年底&#xff0c;全球范围内爆发的新冠疫情蔓延&#xff0c;对各国经济造成了严重冲击&#xff0c;导致贸易活动几近停滞&#xff0c;国际人员流动受限&#xff0c;产业链陷入危机。为应对这一局面&#xff0c;美欧经济体采取了前所未有的扩张性财政和货币政…

高效分割分段视频:提升您的视频剪辑能力

在数字媒体时代&#xff0c;视频剪辑已经成为一项重要的技能。无论是制作个人影片、广告还是其他类型的视频内容&#xff0c;掌握高效的视频剪辑技巧都是必不可少的。本文将介绍如何引用云炫AI智剪高效地分割和分段视频&#xff0c;以提升您的视频剪辑能力。以下是详细的操作步…

设计模式—创建型模式之原型模式

设计模式—创建型模式之原型模式 原型模式&#xff08;Prototype Pattern&#xff09;用于创建重复的对象&#xff0c;同时又能保证性能。 本体给外部提供一个克隆体进行使用。 比如我们做一个SjdwzMybatis&#xff0c;用来操作数据库&#xff0c;从数据库里面查出很多记录&…

半导体产线应用Power Link 转EtherCAT协议网关数字化转型

随着数字化转型的推进&#xff0c;越来越多的企业开始意识到数字化转型的重要性&#xff0c;并将其作为发展战略的关键之一。半导体产线作为一个高度自动化的生产系统&#xff0c;自然也需要数字化转型来提高效率、降低成本和提高质量。Power Link 转EtherCAT协议网关是半导体产…

RISC-V IDE MRS无感远程协助模块详解

RISC-V IDE MRS无感远程协助模块详解 一、说明 1.1 概述 针对RISC-V/ARM等内核MCU的嵌入式集成开发环境MRS(MounRiver Studio)从V1.90版本开始内置无感远程协助模块&#xff08;Sensorless Remote Assistant Module&#xff0c;以下简称SRA模块&#xff09;。SRA模块是一款支…

MAC缓解WebUI提示词反推

当前环境信息&#xff1a; 在mac上安装好stable diffusion后&#xff0c;能做图片生成了之后&#xff0c;遇到一些图片需要做提示词反推&#xff0c;这个时候需要下载一个插件&#xff0c;参考&#xff1a; https://gitcode.net/ranting8323/stable-diffusion-webui-wd14-tagg…

0基础学习VR全景平台篇第114篇:全景图优化和输出 - PTGui Pro教程

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 前情回顾&#xff1a;之前&#xff0c;我们详细介绍了如何用编辑器、控制点、垂直线等功能优化错位和矫正水平&#xff0c;然而这些调整不会马上生效。 我们需要在【优化】选项卡…

python爬虫selenium和ddddocr使用

python爬虫selenium和ddddocr使用 selenium使用 selenium实际上是web自动化测试工具&#xff0c;能够通过代码完全模拟人使用浏览器自动访问目标站点并操作来进行web测试。 通过pythonselenium结合来实现爬虫十分巧妙。 由于是模拟人的点击来操作&#xff0c;所以实际上被反…

UE4 体积云制作 学习笔记

首先Noise本来就是一张噪点图 云的扰动不能太大&#xff0c;将Scale调小&#xff0c;并将InputMin调整为0 形成这样一张扰动图 扰动需要根据材质在世界的位置进行调整&#xff0c;所以Position需要加上WorldPosition 材质在不同世界位置&#xff0c;噪点不同 除以一个数&#…

【Jenkins】新建任务FAQ

问题1. 源码管理处填入Repository URL&#xff0c;报错&#xff1a;无法连接仓库&#xff1a;Error performing git command: ls-remote -h https://github.com/txy2023/GolangLearning.git HEAD 原因&#xff1a; jenkins全局工具配置里默认没有添加git的路径&#xff0c;如果…

【Redis】认识Redis-特点特性应用场景对比MySQL重要文件及作用

文章目录 认识redisredis的主要特点redis的特性&#xff08;优点&#xff09;redis是单线程模型&#xff0c;为什么效率这么高&#xff0c;访问速度这么快redis应用场景redis不可以做什么MySQL和Redis对比启动RedisRedis客户端Redis重要文件及作用 认识redis redis里面相关的小…

SCNet:自校正卷积网络(附代码)

论文地址&#xff1a;https://mftp.mmcheng.net/Papers/20cvprSCNet.pdf 代码地址&#xff1a;https://github.com/MCG-NKU/SCNet 1.是什么&#xff1f; SCNet是一种卷积神经网络&#xff0c;它使用自校准卷积&#xff08;Self-Calibrated Convolutions&#xff09;来增强子…

web:[网鼎杯 2020 青龙组]AreUSerialz

题目 点进题目发现 需要进行代码审计 function __destruct() {if($this->op "2")$this->op "1";$this->content "";$this->process();}这里有__destruct()函数&#xff0c;在对象销毁时自动调用&#xff0c;根据$op属性的值进行…