阻塞队列的使用

news2024/11/25 1:04:16

🎈专栏链接:多线程相关知识详解

目录

一.阻塞队列的介绍

二.使用阻塞队列/生产者消费者模型的好处

1.使用阻塞队列,有利于代码"解耦合"

2.削峰填谷

三.阻塞队列的使用

四.模拟实现阻塞队列


一.阻塞队列的介绍

1.线程是安全的

2.当进行入队操作的时候,队列为满,入队操作就阻塞,直到队列非满的时候入队操作才完成

3.当进行出队操作的时候,队列为空,出队操作就阻塞,直到队列非空的时候出队操作才完成

生产者消费者模型:

例如:3个人包饺子,其中有一个人需要生产饺子皮,他就是生产者,另外的两个人就是消费者,而生产者生产的饺子皮放在桌子上,桌子就是"交易场所".如果生产者生产过快饺子皮已经放满了桌子,他就能进行阻塞等待,如果是饺子皮的生产速度慢于包饺子的速度,那消费者就能够进行阻塞等待

这饺子看起来有点不太一样hhh

二.使用阻塞队列/生产者消费者模型的好处

1.使用阻塞队列,有利于代码"解耦合"

如果服务器A和服务器B直接进行通信,那么A的代码里面需要知道B的存在(A知B),B的代码里也需要知道A的存在(B知A),此时的耦合度就比较,此时如果再多一个服务器C与A进行通讯,则A的代码又要更改,所以此处使用阻塞队列有很大好处

2.削峰填谷

按照没有生产者消费者模型的写法,如果外面用户请求量突增,外面流量过来的压力就会直接压到每一个服务器上,如果某一个服务器抗压能力不行,服务器就容易挂掉.

服务器每处理一个请求,都需要消耗一定的硬件资源(CPU,内存,硬盘,带宽......),同一个时刻的请求越多,所消耗的资源也就越多,一台主机的硬件资源是有限的,当资源耗尽的时候,服务器也就挂了.

分布式系统本质上就是加入了更多的硬件资源

例如:河流上游连续降雨,就会产生汛期,也就相当于是流量暴增,此时如果没有修水库的话,上游河流的水就会直接流到下游去,下游就会发生洪涝灾害,而修水库就是相当于阻塞队列,能够在汛期蓄水,减少河流留到下游的水量,旱期放水,保证下游的河流流量

所以当流量突然暴涨的时候,有使用阻塞队列的话受到冲击的就服务器A和阻塞队列,而其他的服务器就比较不受到影响

三.阻塞队列的使用

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class Demo {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<>(100);
        //带有阻塞的入队操作
        blockingQueue.put(1);
        blockingQueue.put(2);
        blockingQueue.put(3);
        //带有阻塞的出队操作
        Integer ret = blockingQueue.take();
        System.out.println(ret);
        ret = blockingQueue.take();
        System.out.println(ret);
        ret = blockingQueue.take();
        System.out.println(ret);

        ret = blockingQueue.take();//此时就会阻塞等待了
        System.out.println(ret);
    }
}

运行结果:

当前面的三个数字都出队后,队列中就没有元素了,所以带有阻塞的出队操作就会一直等待下去

四.模拟实现阻塞队列

队列的特点是先进先出

class MyBlockingQueue{
    private int[] items = new int[1000];
    private volatile int head = 0;
    private volatile int tail = 0;
    private volatile int size = 0;

    //入队列
    public void put(int elem) throws InterruptedException {
        synchronized (this){
            //判断队列是否为满,满了则不能插入
            while (size >= items.length){
                this.wait();//由take方法里的notify来唤醒
            }
            //进行插入操作,将elem放到items里,放到tail所指向的位置
            items[tail] = elem;
            tail++;
            if(tail >= items.length){
                tail = 0;
            }
            size++;
            this.notify();
        }
    }

    //出队列,返回删除的元素内容
    public Integer take() throws InterruptedException {
        synchronized (this){
            //判断队列是否为空,为空则不能出队
            while (size == 0){
                this.wait();//由put方法里的notify来唤醒
            }
            //非空,取元素
            int ret = items[head];
            head++;
            if(head >= items.length){
                head = 0;
            }
            size--;
            this.notify();
            return ret;
        }
    }
}
public class Demo2 {
    public static void main(String[] args) {
        MyBlockingQueue myBlockingQueue = new MyBlockingQueue();
        Thread producer = new Thread(() ->{//生产者
            int n = 1;
            while (true){
                try {
                    myBlockingQueue.put(n);
                    System.out.println("生产元素:" + n);
                    n++;
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        Thread customer = new Thread(() -> {//消费者
            while (true){
                try {
                    int n = myBlockingQueue.take();
                    System.out.println("消费元素:" + n);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        producer.start();
        customer.start();
    }
}

运行结果: 

在队列中不可能同一时刻出现队列既是空又是满的情况,put和take是对立条件

所以要么是put阻塞,此时take就不会阻塞

       要么是take阻塞,此时put就不会阻塞

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

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

相关文章

[附源码]计算机毕业设计Node.js吃天下美食网站(程序+LW)

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

【AI with ML】第 12 章 :TensorFlow Lite 简介

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

css浮动

浮动的顺序贴靠特性 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>浮动</title><style>.box{width: 250px;height: 100px;border: 1px solid #000;}.box .c1{width: 150px;height: 100p…

云上在野容器攻防战:“杀”不掉的挖矿木马

编者按 数字化浪潮蓬勃兴起&#xff0c;企业面临的安全挑战亦日益严峻。 腾讯安全近期将复盘2022年典型的攻击事件&#xff0c;帮助企业深入了解攻击手法和应对措施&#xff0c;完善自身安全防御体系。 本篇是第二期&#xff0c;讲述了国内某高端制造厂商遭遇云上在野容器攻…

将scss文件转换成css文件

大家平时做项目肯定都习惯了使用scss或者less去写样式&#xff0c;如果是使用工程化的项目我们可以借助插件很方便的将scss或者less转换成css。那如果我们没有使用工程化&#xff0c;比如简单的demo或者官网等项目又希望可以通过scss去编写文件应该怎么办呢&#xff0c;我们可以…

200 万年薪能拿多久?因 ChatGPT 爆红的「提示工程师」竟面临光速失业

【简介】ChatGPT大火后&#xff0c;“提示工程师”开始流行。然而&#xff0c;他们很可能被光速下岗&#xff1f; 最近爆发的ChatGPT真的让人上瘾。 但是&#xff0c;你只是在玩游戏&#xff0c;有些人已经在上面赚取了数百万的年薪&#xff01; 这位名叫莱利古德塞德的小弟最…

Codeforces Round #839 (Div. 3)题解

A. AB? 直接读入字符串然后把下标0和2的数字提取出来就行 // Problem: A. AB? // Contest: Codeforces - Codeforces Round #839 (Div. 3) // URL: https://codeforces.com/contest/1772/problem/A // Memory Limit: 512 MB // Time Limit: 2000 ms // // Powered by CP E…

还在堆人力处理工单?找准耗时源头才是关键!

对于提供企业级服务的公司来说&#xff0c;服务质量与效率日益受到关注。服务质量的本质是整体团队的效能&#xff0c;重中之重则是站在客户视角的工单解决效率。 当下很多这个领域的企业都会设立客户成功中心&#xff0c;其中就有专门对接客户工单处理的职责&#xff1b;而随…

Lifelong Embedding Learning and Transfer for Growing Knowledge Graphs

摘要 现有的知识图谱(KG)嵌入模型主要关注静态KG,但真实世界的KG并不是静态的,而是随着KG应用程序的发展而发展和增长。因此,新的事实和以前看不到的实体和关系不断出现,需要一个嵌入模型,可以通过增长快速学习和转移新知识。基于此,本文研究了KG嵌入的一个扩展领域,即…

96.第十九章 MySQL数据库 -- 多表查询(六)

3.7.2 多表查询 多表查询,即查询结果来自于多张表 子查询:在SQL语句嵌套着查询语句,性能较差,基于某语句的查询结果再次进行的查询 联合查询:UNION,表和表的纵向合并 交叉连接:笛卡尔乘积 内连接: 等值连接:让表之间的字段以“等值”建立连接关系 不等值连接 自然连接…

python数据清洗的三个常用的处理方式!

关于python数据处理过程中三个主要的数据清洗说明&#xff0c;分别是缺失值/空格/重复值的数据清洗。 这里还是使用pandas来获取excel或者csv的数据源来进行数据处理。若是没有pandas的非标准库需要使用pip的方式安装一下。 pip install pandas准备一下需要处理的脏数据&…

【愚公系列】2022年12月 .NET CORE工具案例-PLG轻量级日志可视化服务

文章目录前言1.Serilog简介2.Grafana简介3.Loki是什么一、Serilog对接Grafana轻量级日志可视化服务1.Grafana部署2.Loki部署3.promtail部署4.测试.NET Core写入日志效果5.测试查询日志总结前言 日志功能是几乎所有程序或系统都必备的一个功能。该文章通过使用LokiGrafana来实现…

算法题:N个元素之和

做题思路&#xff1a; 1&#xff09;首先对数组进行排序 2&#xff09;创建一个for循环&#xff1a; 第一个元素指向for循环 3&#xff09;然后创建一个while循环&#xff1b;第二个元素指向for循环的下一个元素&#xff0c;第三个元素指向最后一个元素 4&#xff09;如果三个元…

Java基础之《netty(15)—HTTP服务》

一、使用netty开发一个简单的http服务 1、netty服务器在6668端口监听&#xff0c;浏览器发出请求http://localhost:6668/ 在写netty的http server的例子过程中&#xff0c;发现浏览器使用端口号6668一直无法连接&#xff0c;报错ERR_UNSAFE_PORT。改成7000就可以了。 2、服务器…

2018年高职组——信息评估与管理赛题(解析)

这篇文章为2018年赛题第一阶段DCRS解析 都是自己的想法(仅供参考)不对请指正评论 先来张拓扑养养眼: 2018年拓扑 接下来是IP地址规划表: IP地址的配置就不用我再多赘述了吧,接下来是DCRS的题目 23、DCRS 为接入交换机,为终端产生防止 MAC 地址防洪攻击,请配置端口安全,…

【嵌入式Linux】开发环境搭建

一、概述 在进行某一个芯片平台开发前&#xff0c;一般都需要在电脑上安装一系列软件&#xff0c;然后在这些软件上阅读、编写、编译和调试在该平台上运行的代码&#xff0c;最后将编写好的代码通过某种方式烧录到该芯片的对应地址运行。在电脑上安装的这一系列软件的过程&…

知行之桥2022版本升级之页面变化以及监控邮件答疑

近期有些客户将知行EDI系统升级到了我们最新知行之桥2022版本&#xff0c;升级过程或者升级后对于新版本的使用会有些疑问&#xff0c;根据近期协助大家进行知行EDI系统升级遇到的问题&#xff0c;我们的运维团队整理了一些Q&A&#xff0c;将分为上下两篇分享给大家&#x…

深度学习入门(六十二)循环神经网络——双向循环神经网络

深度学习入门&#xff08;六十二&#xff09;循环神经网络——双向循环神经网络前言循环神经网络——双向循环神经网络课件未来很重要双向RNN推理总结教材1 隐马尔可夫模型中的动态规划2 双向模型2.1 定义2.2 模型的计算代价及其应用3 双向循环神经网络的错误应用4 小结前言 核…

排序算法之直接选择排序(图文详解)

文章目录一、选择排序思想二、排序过程详解2.1 排序的次数2.2 排序演示三、代码范例3.1 SelectSort函数3.2 整体代码实现3.3 结果展示四、选择排序分析4.1 稳定性4.2 复杂度4.3适用场景五、选泽排序优化总结一、选择排序思想 选择排序&#xff08;Selection sort&#xff09;是…

ABBYY15免费版直接编辑PDF格式文件

日常生活中&#xff0c;我们常常使用PDF格式的文件。其优点就是PDF的文本内容不会随着软件版本、电脑字体的变化而变化&#xff0c;保证了其完整性。但也正因为这一点&#xff0c;如果没有源文件&#xff0c;我们就很难对PDF文档的内容进行编辑了。今天&#xff0c;我就向大家展…