【计算机网络】阻塞队列以及生产者消费者模型

目录

  • 阻塞队列
    • 一. 概念
    • 二. 标准库中的阻塞队列
    • 三. 生产者消费者模型
    • 四. 阻塞队列实现
  • 总结

阻塞队列

一. 概念

阻塞队列是⼀种特殊的队列.也遵守"先进先出"的原则.

阻塞队列能是⼀种线程安全的数据结构,并且具有以下特性:

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

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

消费者模式就是通过⼀个容器来解决生产者和消费者的强耦合问题。

生产者和消费者彼此之间不直接通讯,⽽通过阻塞队列来进⾏通讯,所以生产者生产完数据之后不⽤等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,⽽是直接从阻塞队列⾥取.

生产者消费者模型的实现一共有两大步骤:

  1. 实现生产者
  2. 实现消费者

二. 标准库中的阻塞队列

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

  • BlockingQueue是⼀个接⼝.真正实现的类是LinkedBlockingQueue
  • put⽅法⽤于阻塞式的⼊队列,take⽤于阻塞式的出队列
  • BlockingQueue也有offer,poll,peek等⽅法,但是这些⽅法不带有阻塞特性

阻塞队列的伪代码如下:

BlockingQueue<String> queue = new LinkedBlockingQueue<>();// ⼊队列
queue.put("abc");// 出队列. 如果没有 put 直接 take, 就会阻塞.
String elem = queue.take();

三. 生产者消费者模型

public static void main(String[] args) throws InterruptedException {BlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<Integer>();Thread customer = new Thread(() -> {while (true) {try {int value = blockingQueue.take();System.out.println("消费元素: " + value);} catch (InterruptedException e) {e.printStackTrace();}}}, "消费者");customer.start();Thread producer = new Thread(() -> {Random random = new Random();while (true) {try {int num = random.nextInt(1000);System.out.println("生产元素: " + num);blockingQueue.put(num);Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}, "生产者");producer.start();customer.join();producer.join();
}

四. 阻塞队列实现

  1. 通过"循环队列"的⽅式来实现.
  2. 使⽤synchronized进⾏加锁控制.
  3. put插⼊元素的时候,判定如果队列满了,就进⾏wait.(注意,要在循环中进⾏wait.被唤醒时不⼀定,队列就不满了,因为同时可能是唤醒了多个线程).
  4. take取出元素的时候,判定如果队列为空,就进⾏wait.(也是循环wait)
public class BlockingQueue {private int[] items = new int[1000];private volatile int size = 0;private volatile int head = 0;private volatile int tail = 0;public void put(int value) throws InterruptedException {synchronized (this) {// 此处最好使⽤ while.// 否则 notifyAll 的时候, 该线程从 wait 中被唤醒,// 但是紧接着并未抢占到锁. 当锁被抢占的时候, 可能⼜已经队列满了// 就只能继续等待while (size == items.length) {wait();}items[tail] = value;tail = (tail + 1) % items.length;size++;notifyAll();}}public int take() throws InterruptedException {int ret = 0;synchronized (this) {while (size == 0) {wait();}ret = items[head];head = (head + 1) % items.length;size--;notifyAll();}return ret;}public synchronized int size() {return size;}// 测试代码public static void main(String[] args) throws InterruptedException {BlockingQueue blockingQueue = new BlockingQueue();Thread customer = new Thread(() -> {while (true) {try {int value = blockingQueue.take();System.out.println(value);} catch (InterruptedException e) {e.printStackTrace();}}}, "消费者");	customer.start();Thread producer = new Thread(() -> {Random random = new Random();while (true) {					try {blockingQueue.put(random.nextInt(10000));} catch (InterruptedException e) {e.printStackTrace();}}}, "生产者");producer.start();customer.join();producer.join();}
}

总结

  1. 阻塞队列就相当于⼀个缓冲区,平衡了生产者和消费者的处理能⼒.(削峰填⾕)
  2. 阻塞队列也能使生产者和消费者之间解耦.

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

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

相关文章

Git秘籍大公开:从基础概念到高级技巧的全面解析

文章目录 前言一、Git基础介绍1. 作用2. 为什么要进行源代码管理?3. Git的诞生4. Git管理源代码特点5. Git操作流程图解 二、工作区暂存区和仓库区介绍1. 工作区2. 暂存区3. 仓库区 三、Git单人本地仓库操作1. 安装git2. 查看git安装结果3. 创建项目4. 创建本地仓库5. 配置个人…

SpringCloud 负载均衡

目录 一、负载均衡 1、问题 2、什么是负载均衡 服务端负载均衡 客户端负载均衡 二、Spring Cloud LoadBalance 1、使用 Spring Cloud LoadBalance 2、负载均衡策略 3、LoadBalancer 原理 一、负载均衡 1、问题 我们来看一下前面写的代码&#xff1a; List<Serv…

代码随想录算法训练营第六十天| 并查集理论基础、107. 寻找存在的路径

[KamaCoder] 并查集理论基础 [KamaCoder] 并查集理论基础 自己看到题目的第一想法 基础理论, 好奇加不知所以. 看完代码随想录之后的想法 核心思想是将所有节点通过整数数组int[] father串起来, father[u] 表示 u 连接到的顶点. 如果 u 和 v 连接到相同的顶点, 则说明 u 和 …

电子版盖章怎么弄(电子版公章怎么盖上)

下面是利用e章宝盖电子公章更简单&#xff0c;从印章库中选中要盖的公章&#xff0c;然后在文档中想要盖的位置单击一下即可&#xff1a; 第一步&#xff1a;制作需要盖的电子印章 一般是先扫描公章&#xff0c;然后使用e章宝的一键抠章功能&#xff0c;把印章导入到印章库中…

音频demo:使用fdk-aac将PCM数据编码成aac数据

1、README a. 编译 编译demo 本demo是使用的开源项目fdk-aac将PCM数据编码成aac音频文件。由于提供的.a静态库是在x86_64的机器上编译的&#xff0c;所以默认情况下仅支持该架构的主机上编译运行。 $ make编译fdk-aac&#xff08;可选&#xff09; 如果想要在其他架构的CP…

Java语言程序设计——篇二(1)

Java语言基础 数据类型关键字与标识符关键字标识符 常量与变量1、常量2、变量 类型转换自动类型转换强制类型转换 数据类型 数据的基本要素数据的性质&#xff08;数据结构&#xff09;数据的取值范围&#xff08;字节大小&#xff09;数据的存储方式参与的运算 Java是一门强类…

常见的自动化工具开发必备的源代码!

随着科技的飞速发展&#xff0c;自动化工具已经成为我们日常工作中不可或缺的一部分&#xff0c;自动化工具不仅极大地提高了工作效率&#xff0c;还降低了人为错误的可能性。 然而&#xff0c;要想开发出高效、稳定的自动化工具&#xff0c;掌握一些常见的源代码技巧是至关重…

vue中一周的时间选择多个阶段(手动表格选择)

先给大家看一下效果图 源代码 <template><div style"width: 45%"><div style"width: 100%"><div class"time"><div class"timeleft">星期/时间</div><div class"timeright"><…

FastAPI是一个现代、快速(高性能)的Web框架

FastAPI是一个现代、快速&#xff08;高性能&#xff09;的Web框架&#xff0c;专门用于构建基于Python的API。以下是对FastAPI的详细介绍&#xff1a; 一、基本概述 定义与用途&#xff1a;FastAPI是一个开源项目&#xff0c;基于Starlette和Pydantic库构建而成&#xff0c;…

奇安信20240513笔试

题目一 解题思路 n转为字符串&#xff0c;如果位数为偶数&#xff0c;取前一半设为x&#xff0c;后一段为y&#xff0c;从x最低位开始&#xff0c;9&#xff0c;9*10&#xff0c;9*10*10。。。 到最高位&#xff0c;加x&#xff0c;如果x大于或等于y&#xff0c;加1. 位数为奇数…

linux固定主机ip

1.查看虚拟网络配置 NAT设置&#xff1a; 2.修改网卡配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33 TYPE"Ethernet" PROXY_METHOD"none" BROWSER_ONLY"no" BOOTPROTO"static" DEFROUTE"yes" IPV4_FAILURE_FATAL…

idea导入opencv和mediapipe

1.参考pycharm导入cv2_pycharm import cv2-CSDN博客 2.pip install opencv-python 3. python 3.8导入mediapipe 3.1 pip install mediapipe 导入报错&#xff0c; 3.2离线导入 参考Win10安装mediapipe的步骤_mediapipe安装python版本-CSDN博客 首先安装opencv-contrib-py…

Fastjson反序列化漏洞原理与漏洞复现

漏洞原理 1.啥是json? json全称是JavaScript object notation。即JavaScript对象标记法&#xff0c;使用键值对进行信息的存储。举个简单的例子如下&#xff1a; { "name":"BossFrank", "age":23, "media":["CSDN","…

App UI性能测试 - PerfDog使用全教程

App 性能测试指标: 响应、内存、CPU、FPS、GPU渲染、耗电、耗流等。 PerfDog的性能数据更加全面,所以下面以PerfDog来介绍安装使用流程及测试数据的获取与分析。 官网: PerfDog | 全平台性能测试分析专家 第一步,先访问官网进行注册, 注册好账号后,点击下载PerfDog,下…

git 文件没有修改,但一直提示有0行改动,还原也不行

查看文件修改内容 原来是文件的模式(读写可执行权限)发生了变化,内容本是没有变化. 怎么解决 git config --add core.filemode false忽略文件模式

ES6 之 Set 与 Map 数据结构要点总结(一)

Set 数据结构 Set 对象允许你存储任何类型的唯一值&#xff0c;无论是原始值还是对象引用。 特性&#xff1a; 所有值都是唯一的&#xff0c;没有重复。值的顺序是根据添加的顺序确定的。可以使用迭代器遍历 Set。 常用方法&#xff1a; 1. add(value)&#xff1a;添加一个新…

Vue90-Vuex模块化:namespace

一、模块化的目标 当业务很复杂的时候&#xff0c;各个模块中的内容会很多&#xff0c;所以&#xff0c;要将不同业务功能的模块放到不同的位置 二、实现 2-1、模块内容的拆分 将对应的模块的内容&#xff0c;添加到对应的对象中去。 2-2、拆分后模块的使用 1、方式一 2、方…

创建react的脚手架

Create React App 中文文档 (bootcss.com) 网址&#xff1a;creat-react-app.bootcss.com 主流的脚手架&#xff1a;creat-react-app 创建脚手架的方法&#xff1a; 方法一&#xff08;JS默认&#xff09;&#xff1a; 1. npx create-react-app my-app 2. cd my-app 3. …

2024年信息素养大赛图形化编程小低组复赛真题-附答案 6547网

2024年全国青少年信息素养大赛图形化编程小低组复赛真题 题目总数&#xff1a;6 总分数&#xff1a;100 第1部分 第 1 题 问答题 【编程实现】点击小绿旗&#xff0c;实现将鱼的所有造型印到舞台区 【具体要求】 1. 将鱼显示出来 全部擦除所有内容 2. 将鱼的造型设…

python 10个自动化脚本

目录 &#x1f31f; 引言 &#x1f4da; 理论基础 &#x1f6e0;️ 使用场景与代码示例 场景一&#xff1a;批量重命名文件 场景二&#xff1a;自动下载网页内容 场景三&#xff1a;数据清洗 场景四&#xff1a;定时执行任务 场景五&#xff1a;自动化邮件发送 场景六…