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

【javaEE】多线程初阶(Part6 阻塞队列)

目录

  • 前言
  • 阻塞队列
    • 1. 阻塞队列
    • 2. 生产者消费者模型
    • 3. 阻塞队列的具体使用
  • THINK


前言

今天不学习,明天边垃圾

本文的主要内容:多线程案例中的【阻塞队列 + 生产者消费者模型】。


阻塞队列

1. 阻塞队列

  1. (了解)编译器优化:不仅仅是编译器在做优化,也可能是操作系统和CPU在做优化
  2. 队列:先进先出;然而,并不是所有的队列都是“先进先出”,“先进先出”针对的是普通的队列,复杂队列就不一定“先进先出”。
    如:非“先进先出”:
    ① 优先级队列PriorityQueue
    ② 消息队列(在队列元素中引入一个“类型”,此时的“类型”是指业务上的类型):入队列的时候没啥,但是出队列的时候会指定某个类型的元素先出。
  • 【常用,所以工作中经常把消息队列这样的数据结构单独实现成一个小程序,并且部署在一组服务器上,称为“消息队列服务器”,也就是平时常说的“MQ”,其实也就是一种常用的“中间件”
  • “中间件”其实就是一类“通用”服务器的统称,与业务无关,如MySQL】
  1. 阻塞队列是一个特殊的队列,但是其确实是 “先进先出” 的。

  2. 阻塞队列特点:
    ① 线程安全
    ② 带有阻塞功能:
    A)如果队列满了还继续入队列,此时入队操作就会阻塞;直到队列不满,入队列才能成功
    B)如果队列空了还继续出队列,此时出队操作就会阻塞;直到队列不空,出队列才能成功

  3. 阻塞队列的典型应用场景:生产者-消费者模型(描述的是多线程协同工作的一种方式),该模型能够较好地解决锁冲突问题。 (举例:包饺子)

2. 生产者消费者模型

  1. 生产者-消费者模型 / 阻塞队列的其他好处:
    ① 使用阻塞队列,有利于代码 “解耦合”

耦合:两个模块之间的关联关系,关系越紧密则耦合性越高。
【如:两个服务器直接通信则关联性强,互相影响;
但是如果在两个服务器之间加上一个阻塞队列就有效降低了两个服务器的关联性,耦合性降低,并且这样的话增加/删除服务器也较为方便】

  • 也就是说: 生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,此时的阻塞队列就类似于“缓冲区”

② 削峰填谷:(举例:三峡水库)
如果按照没有 生产者消费者模型的写法,外面流量过来的压力就会直接压在每个服务器上,如果某个服务器抗压能力不太行就容易挂。

  • 为什么一个服务器同一时刻收到很多请求就挂了?
    理由:服务器每处理一个请求都是需要消耗一定的硬件资源,这些硬件资源包括但不限于CPU、内存、硬盘、宽带等,同一时刻请求越多则消耗的资源越多;而一台主机的硬件资源是有限的,一旦某个硬件资源耗尽了,此时机器也就挂了。
    【而所谓的分布式系统,本质上就是加入了更多的硬件资源】
  • 如果使用阻塞队列,当流量骤增的时候,生产者和阻塞队列就承受了压力,而其余消费者还是按照原来的节奏来消费数据,即对消费者的冲击就不大。

3. 阻塞队列的具体使用

(队列有三个基本操作:入队列、出队列、取 队首元素)

  1. 阻塞队列提供给了带有阻塞的入队列和出队列方法,但是没有提供带有阻塞的取队首元素方法。

  2. 标准库的阻塞队列
    Demo1标准库
    1)BlockingQueue 也有 offer, poll, peek 等方法, 但是这些方法不带有阻塞特性。而put、take方法带有阻塞。
    2) BlockingQueue是接口。

  3. 自己实现一个阻塞队列
    1) 先实现一个普通队列
    (队列的实现有两个版本:基于链表、基于数组):这里写基于数组的版本(循环队列)
    ① 循环队列:下标head/tail 如果head == tail就是null/满,如果存入数据则tail++,并且队列中有效元素范围是[head,tail); 而如果到达末尾就又回到开头,达到循环
    ② 如何区分该队列是空还是满呢?空和满都是head==tail,即指针重合,区分方法就是:要么加一个记录个数的变量,要么浪费一个空间
    (具体参考博客:队列实现(循环队列))
    2)加上线程安全 (线程安全就是加锁synchronized)
    3)加上阻塞实现(队列为空则出队列阻塞,队列满则入队列阻塞)
    这里注意稳妥的写法,wait不一定是另一个线程中的notify来唤醒的,也可能是interrupt来唤醒的,如果是interrupt唤醒可能条件就还不成熟,所以需要循环再判断。
    wait被唤醒之后也是要去竞争锁的

Demo2 生产者消费者模型+自己实现阻塞队列
(尽可能看注释+每次提交)


THINK

  1. 阻塞队列的经典应用场景:生产者消费者模型
  2. 阻塞队列的实现(尤其注意模拟实现:普通队列的实现+加锁+实现阻塞安全)
  3. 标准库中的阻塞队列(接口)
  4. 阻塞队列的实现注意唤醒与等待!!

相关文章:

  • java-php-python-中小型超市管理系统计算机毕业设计
  • 如何使用Jupyter Notebook
  • MongoDB 数据库(一):MongoDB的介绍与安装
  • 数商云采购管理系统:采购业务模式介绍,助力汽车零部件企业采购业务高效协同
  • 【变化检测】国土资源典型要素变化遥感智能监测关键技术及应用
  • 计算机毕设(附源码)JAVA-SSM基于的影评系统
  • Ts内置类型---下
  • 前端面试真题宝典(二)
  • 【Linux】gcc/g++ 和 gdb git工具的基本使用方式
  • 逻辑控制2——循环结构
  • 细节决定成败:探究Mybatis中javaType和ofType的区别
  • 11月最新PS2023软件来了,搭配最新Adobe 2022!支持M1
  • FPGA新起点V1开发板(三)——Quartus II软件的使用(流水灯的烧录以及sof转jic的方法记录)
  • 清华学姐三年的测试成长经历,到最后的喜提高薪offer
  • Python第五章 函数
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • Apache的80端口被占用以及访问时报错403
  • Elasticsearch 参考指南(升级前重新索引)
  • HomeBrew常规使用教程
  • IOS评论框不贴底(ios12新bug)
  • java8-模拟hadoop
  • OSS Web直传 (文件图片)
  • tab.js分享及浏览器兼容性问题汇总
  • vue2.0项目引入element-ui
  • 读懂package.json -- 依赖管理
  • 今年的LC3大会没了?
  • 警报:线上事故之CountDownLatch的威力
  • 区块链技术特点之去中心化特性
  • 设计模式 开闭原则
  • 事件委托的小应用
  • 由插件封装引出的一丢丢思考
  • 浅谈sql中的in与not in,exists与not exists的区别
  • ​ArcGIS Pro 如何批量删除字段
  • ​linux启动进程的方式
  • ​比特币大跌的 2 个原因
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (力扣)1314.矩阵区域和
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (四)c52学习之旅-流水LED灯
  • (五)c52学习之旅-静态数码管
  • (五)MySQL的备份及恢复
  • (转)使用VMware vSphere标准交换机设置网络连接
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • .bat文件调用java类的main方法
  • .NET 5种线程安全集合
  • .NET 药厂业务系统 CPU爆高分析
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .NET导入Excel数据