Javaee:阻塞队列和生产者消费者模型

news2024/11/22 16:48:16

文章目录

  • 什么是阻塞队列
  • java中的主要阻塞队列
  • 生产者消费者模型
    • 阻塞队列发挥的作用
      • 解耦合
      • 削峰填谷
  • 模拟实现阻塞队列
    • put方法
    • take方法
    • 生产者消费者模型

什么是阻塞队列

阻塞队列是一种支持阻塞操作的队列,在多线程中实现通线程之间的通信协调的特殊队列

java中的主要阻塞队列

java中的阻塞队列是一个接口BlockingQueue<>

带有实例化类有:

ArrayBlockingQueue(有界队列)
LinkedBlockingQueue(无界队列)
ProrityBlockingQueue(FIFO队列)

阻塞队列不仅继承了队列的所有方法,还提供了带有阻塞效果的put方法和take方法

put(E e):将元素插入队列,如果队列满,则等待直到队列有空间。
take():从队列中取出并移除元素,如果队列为空,则等待直到队列有元素。

特点

线程安全

阻塞特性

队列为空,尝试出队列,出队列操作就会阻塞,阻塞到其他线程添加元素为止

队列为满,尝试进队列,进队列操作也会阻塞,阻塞到其他线程取走元素为止

在这里插入图片描述
以上是线程一往阻塞队列添加元素,线程二从阻塞队列中移除元素

理解有界和无界

有界:在实例化对象的时候,可以在构造方法传参,表示阻塞队列能容纳的最大元素个数
无界:没有设置固定大小的队列,表示可以存储的元素个数范围很大

生产者消费者模型

在这里插入图片描述
阻塞队列是生产者消费者模型的交易场所

举个生活中的例子

包饺子
奶奶负责擀饺子皮,奶奶把饺子皮放到一个容器里,我和妈妈把饺子皮从容器中拿出来包饺子。

饺子皮——>资源

奶奶——>生产者

我和妈妈——>消费者

容器——>交易场所(阻塞队列)

阻塞队列发挥的作用

解耦合

举例
服务器A直接与服务器B进行交互,一旦服务器A中的代码发生改变,服务器B越需要做出相应的改变,也就是他们之间的关联度高,耦合度高
在这里插入图片描述

解耦合——通过阻塞队列

在这里插入图片描述
服务器A不直接与服务器B进行交互,而是通过阻塞队列这个交易场所进行交互,降低了服务器之间的关联度

在生产者消费者模型中的应用

阻塞队列通过充当中间缓存,允许生产者先把数据放入队列,消费者在有空闲时再取出处理,这样就不会因为速度不一致而导致数据丢失或重复处理

削峰填谷

如果服务器A传给B的数据量激增,服务器B没有那么大的接收量,就会瞬间过载

削峰填谷——阻塞队列
在这里插入图片描述

在请求量突然增加的情况下,阻塞队列可以缓冲住大量的生产者请求,避免消费者瞬时过载。
当生产量较小时,消费者可以逐步消费队列中积累的数据,从而实现负载平衡和资源优化。

模拟实现阻塞队列

put方法

public void put(String elem) throws InterruptedException {
        synchronized(locker) {//保证原子性
            // 使用while循环来检查队列是否已满,以处理虚假唤醒和条件变化的情况
            while (size >= data.length) {//if的话会出问题,使用wait需要搭配while进行二次判断,如果唤醒wait之后,size还是为0,那么执行下面的操作就会出问题
               //如果队列已满,则当前线程等待,直到被其他线程唤醒
                locker.wait();//抛一下异常
            }
            data[tail] = elem;
            tail++;
            if (tail >= data.length) {
                tail = 0;//便于理解
                //tail=(tail+1)%data.length;

            }
            size++;
            locker.notify();//说明不为空就去唤醒take的wait
        }
    }

take方法

public String take() throws InterruptedException {
        synchronized (locker) {//保证原子性
            // 使用while循环来检查队列是否为空,以处理虚假唤醒和条件变化的情况
            if (size == 0) {
                locker.wait();// 如果队列为空,则当前线程等待,直到被其他线程唤醒
            }

            String ret = data[head];
            head++;
            if (head >= data.length) {
                head = 0;
            }
            size--;
            // 在取出元素并更新队列状态后,通知其他等待的线程
            locker.notify();//相互唤醒,说明没满,就去唤醒put的wait
            return ret;
        }
    }

生产者消费者模型

Thread producer=new Thread(()->{
            int n=0;
            try {
                while(true){
                    queue.put(n+" ");
                    System.out.println("生产元素"+n);
                    n++;
                }
            } catch (InterruptedException e) {
               throw new RuntimeException(e);
            }
        },"生产者");
        Thread consumer=new Thread(()->{
            while(true){
                String n=null;
                try {
                        n=queue.take();
                        System.out.println("消费元素"+n);
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        Thread consumer2=new Thread(()->{
            while(true){
                String n=null;
                try {
                    n=queue.take();
                    System.out.println("消费元素"+n);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

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

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

相关文章

git仓库分支

操作 切换分支 git checkout 1.2.5 git checkout 1.3.0 使用命令切换分支之后&#xff0c;代码内容加载过后也是切换好的

安卓基础001

前言 也是好久没有更新博客了,最近实习也是需要学习一些知识哈哈哈哈哈哈为了更好的发展嘛,咱们从客户端开始,过程可能有点像写前端,不喜勿喷,希望在学习的过程中也可以给大家带来一些简单得帮助吧....... tips:这里跳过安卓studio安装,大家可自行寻找教程 写的不详细,只是为了…

使用web.dev提供的工具实现浏览器消息推送服务

文章目录 前言实现工具和效果实现原理实现过程前端接收用户订阅请求将用户订阅信息更新到后端后端实现接收并保存订阅信息的接口后端实现消息推送的逻辑前言 对于电商独立站来说,新品上架或者促销活动上线及时通知到用户是很重要的,通知的渠道有很多,其中就包括浏览器消息推…

在Bash脚本中 set -e 是什么意思

问题 我正在研究这个预安装(preinst)脚本的内容&#xff0c;该脚本会在从 Debian 软件包(.deb)文件解压该包之前执行。 脚本包含以下代码&#xff1a; #!/bin/bash set -e # Automatically added by dh_installinit if [ "$1" install ]; thenif [ -d /usr/share…

服务器宝塔安装哪吒监控

哪吒文档地址&#xff1a;https://nezha.wiki/guide/dashboard.html 一、准备工作 OAuth : 我使用的gitee&#xff0c;github偶尔无法访问&#xff0c;不是很方便。第一次用了极狐GitLab&#xff0c;没注意&#xff0c;结果是使用90天&#xff0c;90天后gg了&#xff0c;无法登…

JavaEE初阶---网络原理(四)--IP协议/DNS协议

文章目录 1.初识网络层&#xff08;了解即可&#xff09;2.地址管理2.1动态分配2.2网络地址转换2.3IP-v6最终解 3.网段划分4.以太网协议--数据链路层5.DNS应用层协议 1.初识网络层&#xff08;了解即可&#xff09; 网络层做的事情就是下面的两个&#xff1a; 1&#xff09;地…

邮件发送excel带预览excel功能

excel 打开后的内容: 思路&#xff1a; 1、邮件发送excel 是作为附件发送出去的&#xff1b; 2、excel 预览是&#xff0c;必须另外点击预览按钮&#xff0c;并不能直接预览邮件内容然后在邮件主体内容展示出来 根据以上两点基本没法实现 邮件发送后邮件自带 预览功能。 伪方法…

Spring Boot 3 + Spring Security + Knife4j 无法访问 Swagger 文档的问题及解决方案

背景介绍 在使用Spring Boot 3框架结合Spring Security进行项目开发时&#xff0c;我们可能会遇到集成Knife4j后Swagger文档无法正常访问的情况。本文将探讨可能的原因以及相应的解决办法。 常见问题 问题描述 当配置好Spring Security后尝试通过Knife4j访问API文档页面时&…

构建校园社团信息管理平台:Spring Boot技术的核心要点

6系统测试 6.1概念和意义 测试的定义&#xff1a;程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为&#xff1a; 目的&#xff1a;发现程序的错误&#xff1b; 任务&#xff1a;通过在计算机上执行程序&#xff0c;暴露程序中潜在的错误。 另一个…

Spring 框架中常见的注解(Spring、SpringMVC、SpringBoot)

1. Spring 中常见注解 还有Recourse&#xff1a;相当于AutowiredQualifier Value : 用于将配置文件中的值注入到Bean的字段中。 Bean : 用于在配置类中声明一个Bean。 Lazy : 用于延迟加载Bean。 2. SpringMVC 中常见注解 还有GetMapping PostMapping PutMapping DeleteMapp…

深度学习笔记之BERT(一)BERT的基本认识

深度学习笔记之BERT——BERT的基本认识 引言回顾&#xff1a;Transformer的策略回顾&#xff1a;Word2vec的策略和局限性 BERT \text{BERT} BERT的基本理念抽象的双向BERT的预训练策略 预训练与微调 引言 从本节开始&#xff0c;将介绍 BERT \text{BERT} BERT系列模型以及其常…

【华为HCIP实战课程二十八】中间到中间系统协议IS-IS邻居关系排错,网络工程师

一、ISIS邻居关系条件 1、同一层次(比如Level-2路由器不能和Level-1路由器形成邻居关系) 2、同一区域(L1必须同一区域) 3、同一网段 R1和R2之间分别配置如下IP地址和掩码: R1 的接口S1/0/0掩码为/24 R2的接口S1/0/0配置成掩码/28: 此时R1和R2依然可以建立ISIS邻居关系…

微信小程序,打开新的项目,调试遇见[ app.json 文件内容错误] app.json: 在项目根目录未找到 app.json

1&#xff0c;首先&#xff0c;在开发工具右上角&#xff0c;打开详情&#xff1b;设置基础库&#xff1b;3.6.3 2&#xff0c;第二步&#xff0c;在项目目录下&#xff0c;找到app.json文件存在 3&#xff0c;第三步&#xff0c;修改项目根目录下&#xff0c;project.config.j…

使用RabbitMQ实现微服务间的异步消息传递

使用RabbitMQ实现微服务间的异步消息传递 RabbitMQ简介 安装RabbitMQ 在Ubuntu上安装RabbitMQ 在CentOS上安装RabbitMQ 配置RabbitMQ 创建微服务 生产者服务 安装依赖 生产者代码 消费者服务 消费者代码 运行微服务 消息模式 直接模式 生产者代码 消费者代码 扇出模式 生产…

数字教学的创新引擎:构建数字教学知识库

在教育行业&#xff0c;数字化转型正成为推动教育现代化的重要力量。数字教学知识库作为这一转型的核心组成部分&#xff0c;对于整合教育资源、提升教学质量、促进教育公平具有重要意义。本文将探讨数字教学知识库的构建策略、应用价值&#xff0c;并分析其在教育行业的深远影…

【ArcGISPro】制作简单的ArcGISPro-AI助手

【python】AI Navigator的使用及搭建本机大模型_anaconda ai navigator-CSDN博客 【Python】AI Navigator对话流式输出_ai大模型流式输出效果(打字效果) python-CSDN博客 【C#】调用本机AI大模型流式返回_怎么实现调用本地大模型时实现流式输出-CSDN博客 【ArcGISPro】宣布推…

web文件包含include

php伪协议 在 PHP 中&#xff0c;伪协议&#xff08;Pseudo Protocols&#xff09; 也被称为 流包装器&#xff0c;这些伪协议以 php:// 开头&#xff0c;后面跟着一些参数&#xff0c;用于指定 要执行的操作 或 需要访问的资源。 伪协议表明这些协议并不是一个 真实的外部协议…

【力扣打卡系列】验证二叉搜索树

坚持按题型打卡&刷&梳理力扣算法题系列&#xff0c;语言为go&#xff0c;Day17 验证二叉搜索树 题目描述 解题思路 前序遍历&#xff1a;先访问节点值&#xff0c;再访问左右子树有效二叉搜索树的定义 节点的左子树只包含小于当前节点的数节点的右子树只包含大于当前节…

【天线&空中农业】蜜蜂检测系统源码&数据集全套:改进yolo11-ASF

改进yolo11-dysample等200全套创新点大全&#xff1a;蜜蜂检测系统源码&#xff06;数据集全套 1.图片效果展示 项目来源 人工智能促进会 2024.10.30 注意&#xff1a;由于项目一直在更新迭代&#xff0c;上面“1.图片效果展示”和“2.视频效果展示”展示的系统图片或者视频可…

hive将包含逗号的字段拆分为多列

目录 一、概述 二、行动 1.准备数据 2.数据清洗 3.substring_index函数 4.split函数实现 一、概述 想将hive表中包含逗号的字段按逗号做分隔符进行分列操作 二、行动 1.准备数据 --1 select {1,2,3,4,5,6,7,8} as num_str --使用的数据2.数据清洗 --2 select num_s…