阻塞队列和生产消费模型

阻塞队列

阻塞队列的概念

队列相信我们已经不陌生了 之前也学过很多队列 比如: 普通队列优先级队列 两种
这两种队列都是线程不安全的
而我们讲的阻塞队列 刚好可以解决线程安全问题 也是先进先出 并且带有阻塞功能.
阻塞功能是怎么回事呢

就是如果入队的时候阻塞队列为满 ,则当前线程就会进入阻塞状态,阻塞到有出队列操作才会再唤醒线程继续执行 ,相同 如果出队时阻塞队列为空,则当前线程也会进入阻塞状态 直到有新元素入队操作才会唤醒继续执行该线程.

在Java标准库中,BlockingQueue这个就是标准库提供的阻塞队列. 阻塞队列在实际开发中使用的场景十分广泛. 在阻塞方法中 有独特的进队列和出队列的方法 其他一些普通的方法阻塞队列也有 ,但是使用阻塞队列一般都不会再使用普通队列的方法了.

消息队列

消息队列这种数据结构其实也是阻塞队列的一种 ,也带有阻塞特性.它不是普通的先进先出,而是通过topic这样的参数来对数据进行分类,出队列的时候,指定topic,每个topic下的数据是先进先出. 消息队列只要应用于生产者消费者模型.

生产者消费者模型

什么是生产者和消费者模型呢 ?
举个例子:
就相当于两个人制作饺子 要分为两步 一步是擀饺子皮 一步是包饺子. 要两个人分工合作,实际上 要包饺子就得先擀饺子皮 那擀饺子皮的人相当于生产者 包饺子皮的人就相当于消费者 擀好的饺子皮要用一个容器来盛放 ,而这个容器就相当于阻塞队列/消息队列. 有了这个容器就会有阻塞功能 ,现在A擀饺子皮 B包饺子 如果B包饺子包得快 A擀饺子皮慢 那容器里面的饺子皮很快就会空了 这时候B就要阻塞等待A擀饺子皮 每擀一个就包一个饺子 ,相反 如果A擀饺子皮擀得比较快 B包饺子慢,那么容器很快就会满了,这样A就会阻塞等待 B包饺子 B每包一个 A就擀一个.

在这里插入图片描述
上面图片就是生产者和消费者模型

你们想一想 在实际开发中为什么要用到这个生产者消费者模型 ? 相当于在开发中 有两种服务器 :请求服务器Q和应用服务器Y 如果QY直接传递消息 ,没有阻塞队列的情况下,如果Q突然请求有很多的时候,Y的请求也就会跟着暴涨 ,但Y服务器是应用服务器,他处理任务的过程很复杂 是重量级的 这样就会让Y服务器直接G.

这时我们如果我们引入生产者消费者模型,这样即使Q服务器的请求再怎么多,也不会影响到Y服务器 最坏的情况也就是Q服务器挂了 但Y服务器不会有任何影响 因为Q的请求都会放在阻塞队列中 , 有界 的阻塞队列就会引起阻塞 Y服务器 还是和原来一样处理这些请求 这样就起到了"削峰填谷"的作用.
这个模型还有一个优势就是高内聚低耦合 两个服务器不会直接接触 一个挂了不会对另一个产生影响.

用循环队列实现一个简单的阻塞队列 用于实现一个生产者消费者模型

第一种 就是生产者生产快 而消费者慢 就会出现 程序一运行生产者咔咔就会生产满了 接下来就会阻塞 消防者每消费一个 生产者才会生产一个. 下面我们通过代码来实现一下:

class MyBlockingQueue{
    private String[] elems = null;
    private volatile int head = 0;
    private volatile int tail = 0;
    private volatile int size = 0;

    public MyBlockingQueue(int capacity) {
        elems = new String[capacity];
    }

    void put(String elem) throws InterruptedException {
        //先加锁
        synchronized (this) {
            while (size >= elems.length) {
                //队列满了 ,就要等待
                this.wait();
            }

            //把新的元素放到tail所在的位置上
            elems[tail] = elem;
            tail++;
            if (tail >= elems.length) {
                //到达末尾  ,就回到开头
                tail = 0;
            }
            //更新size的值
            size++;
            //唤醒下面take的wait
            this.notify();
        }
    }

    String take() throws InterruptedException {
        synchronized (this) {
            while (size == 0) {
                //为空要等待
                this.wait();
            }
            //取出 head指向的元素
            String result = elems[head];
            head++;
            if (head >= elems.length) {
                head = 0;
            }

            size--;
            //唤醒put上面的wait
            this.notify();
            return result;
        }

    }
}

public class Text2 {
    //实现一个阻塞队列 模拟一个生产者消费者模型
    public static void main(String[] args) {
        //实例化一个阻塞队列的对象   利用该阻塞队列实现一个生产者消费者模型
        MyBlockingQueue queue = new MyBlockingQueue(1000);

        //生产者线程
        Thread t1 = new Thread(() -> {
            try {
                int count = 0;
                while (true) {
                    queue.put(count + "");
                    System.out.println("生产:" + count);
                    count++;
                }
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        //消费者线程
        Thread t2 = new Thread(() ->{
            try {
                while (true) {
                    String result = queue.take();
                    System.out.println("消费:" + result );
                    Thread.sleep(1000);
                }
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t1.start();
        t2.start();
    }
}

运行截图:
在这里插入图片描述
其实这里生产者和消费者的频率和快慢 我们都是可以通过代码来控制的 .
上面就是阻塞队列的应用场景 .

相信通过上诉内容 大家都了解并掌握阻塞队列了吧!

下一章内容 : 我们就会讲到线程池的有关内容 .

谢谢大家的浏览 !!!

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

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

相关文章

深入解析API技术:原理、实现与应用

在现代软件开发中,API(应用程序接口)扮演着至关重要的角色。API 允许不同的软件应用程序和系统之间进行通信和数据交换,从而构建出更加高效、灵活和可扩展的软件解决方案。本文将深入解析API技术的原理、实现方法,并附…

iptables/ebtables学习笔记

目录 一、前言 二、Netfilter 构成 三、Netfilter 转发框架 四、Netfilter 与 iptables 五、Netfilter 与 ebtables 一、前言 Netfilter 是 Linux 内核的数据包处理框架,由 Rusty Russell 于 1998 年开发, 旨在改进以前的 ipchains(Lin…

中霖教育:一级建造师能跨省考吗?

一级建造师是可以跨省考的,对于考生的户籍地并没有限制,只要符合参加考试的条件就可以报名。 但是,对于异地报名参加一级建造师考试的考生,必须经过严格的资料审核流程。考生在报名过程中需要提交居住证明、工作证明、以及异地考…

c语言例题,求数组中最大值,99乘法口诀表

例题1:求出数组中最大的值 根据题意,我们知道的是需要从一个数组中找到一个最大的元素并且输出。那首先我们先建立一个数组,然后将一些不有序的整型元素放到数组中,然后再建立一个变量来存放数组中的第一个元素,通过一…

第23次修改了可删除可持久保存的前端html备忘录:增加了百度引擎

第22次修改了可删除可持久保存的前端html备忘录视频背景分离&#xff0c;增加了本地连接&#xff0c;增加了纯CSS做的折叠隐藏修改说明 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport…

(三)ffmpeg 解码流程以及函数介绍

一、视频解码流程 二、函数介绍 1.avformat_network_init 函数作用&#xff1a; 执行网络库的全局初始化。这是可选的&#xff0c;不再推荐。 此函数仅用于解决旧GnuTLS或OpenSSL库的线程安全问题。如果libavformat链接到这些库的较新版本&#xff0c;或者不使用它们&#…

跟TED演讲学英文:The dark side of competition in AI by Liv Boeree

The dark side of competition in AI Link: https://www.ted.com/talks/liv_boeree_the_dark_side_of_competition_in_ai Speaker:Liv Boeree Date: October 2023 文章目录 The dark side of competition in AIIntroductionVocabularyTranscriptSummary后记 Introduction Co…

react 初学增删改查购物车案例

界面 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>react-购物车案例</title><…

[MQTT]Mosquitto的簡介、安裝與本機連接測試

MQTT(Message Queuing Telemetry Transport)是基於發布/訂閱模式(Publish/Subscribe)的輕量級網絡通訊協議&#xff0c;專用於在低帶寬、不可靠的網絡環境中傳輸數據&#xff0c;關於工作原理和優點如下: 1.發布/訂閱模式(Publish/Subscribe) 發布者將消息發布特定的主題(top…

MIPI CSI-2 虚拟通道

一、背景 在介绍虚拟通道之前&#xff0c;我们先描述一个场景&#xff0c;主控芯片只有 4 个 D-PHY VIN 接口&#xff0c;但是产品需要4 个以上的摄像头。 如上图所示&#xff0c;如果我们把摄像头和主控芯片直接通过 D-PHY 接口连接&#xff0c;最多只能接 4 个摄像头&#x…

【Linux】基础IO----理解缓冲区

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;理解缓冲区 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不会坚持。早安! > 专栏选自&#xff1a;Linux初阶 > 望…

Linux 系统解压缩文件

Linux系统&#xff0c;可以使用unzip命令来解压zip文件 方法如下 1. 打开终端&#xff0c;在命令行中输入以下命令来安装unzip&#xff1a; sudo apt-get install unzip 1 2. 假设你想要将zip文件解压缩到名为"target_dir"的目录中&#xff0c;在终端中切换到目标路…

ActiveMQ介绍及linux下安装ActiveMQ

ActiveMQ介绍 概述 ActiveMQ是Apache软件基金下的一个开源软件&#xff0c;它遵循JMS1.1规范&#xff08;Java Message Service&#xff09;&#xff0c;是消息队列服务&#xff0c;是面向消息中间件&#xff08;MOM&#xff09;的最终实现&#xff0c;它为企业消息传递提供高…

基于腾讯云手把手教你搭建网站全流程,2024年最新建站教程

使用腾讯云服务器搭建网站全流程&#xff0c;包括轻量应用服务器和云服务器CVM建站教程&#xff0c;轻量可以使用应用镜像一键建站&#xff0c;云服务器CVM可以通过安装宝塔面板的方式来搭建网站&#xff0c;腾讯云服务器网txyfwq.com整理使用腾讯云服务器建站教程&#xff0c;…

2011年认证杯SPSSPRO杯数学建模B题(第一阶段)生物多样性的评估全过程文档及程序

2011年认证杯SPSSPRO杯数学建模 B题 生物多样性的评估 原题再现&#xff1a; 2010 年是联合国大会确定的国际生物多样性年。保护地球上的生物多样性已经越来越被人类社会所关注&#xff0c;相关的大规模科研和考察计划也层出不穷。为了更好地建立国际交流与专家间的合作&…

sql注入技术总结

Sql注入判断数据库类型 Mysql注入 如果对应的表&#xff0c;列名爆不出来&#xff0c;可以尝试用字符转16进制转化。 相关函数&#xff1a; system_user() 系统用户名 user() 用户名 current_user 当前用户名 session_user()连接数据库的用户名 database() 数据库名 ver…

5G Frequency Bands 频率分布

连接&#xff1a;https://www.5g-networks.net/5g-technology/5g-frequency-bands/

项目5-博客系统1(准备工作+博客列表+博客详情页)

1.创建项目 导入以下依赖 2.项目介绍 使⽤SSM框架实现⼀个简单的博客系统 共5个页面 2.1 前端页面展示 2.1.1 用户登录 2.1.2 博客发表页 2.1.3 博客编辑页 2.1.4 博客列表页 2.1.5博客详情页 2.2 功能描述: ⽤⼾登录成功后, 可以查看所有⼈的博客. 点击 <<查看全⽂…

CSS基础+基本选择器和复合选择器(如果想知道CSS的基础+基本选择器和复合选择器知识点,那么只看这一篇就足够了!)

前言&#xff1a;在我们学习完了html之后&#xff0c;我们就要开始学习三大件中的第二件—CSS&#xff0c;CSS 可以控制多重网页的样式和布局&#xff0c;也就是将我们写好的html代码加上一层华丽的衣裳&#xff0c;使网页变得更加精美。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨…

uni-app如何生成骨架屏

为什么需要骨架屏&#xff1a;为了缓解用户打开程序时等待接口的焦虑情绪 1.打开微信开发者工具&#xff0c;找到模拟器中的页面信息&#xff0c;选择生成骨架屏 2.将生成的wxml代码复制到vscode&#xff0c;在index的components中新建一个vue文件&#xff0c;只需保留请求接口…