8.多线程之阻塞队列

news2024/11/27 18:39:01

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

文章目录

  • 阻塞队列和生产者消费者模型
  • 1. 阻塞队列
  • 2. Java标准库中的阻塞队列 - BlockingQueue
  • 3. 阻塞队列的实现
  • 4. 生产者消费者模型

1. 阻塞队列

    阻塞队列是什么呢?阻塞队列是一种特殊的队列,满足队列的基本要求 - 先进先出。同时阻塞队列使一种线程安全的数据结构。不过阻塞队列相较于普通队列也有着它的特殊之处。

  1. 线程安全
  2. 队列满时,继续插入元素,队列会阻塞,直到其它线程从队列中取出元素。
  3. 队列空时,继续删除元素,队列会阻塞,直到其它线程从队列中插入元素。

    阻塞队列的一个典型应用场景就是 “生产者消费者模型”,后面我们也将介绍到。

2. Java标准库中的阻塞队列 - BlockingQueue

    Java 标准库中内置了阻塞队列。在大部分场景下,Java提供的阻塞队列已经足够满足我们如果我们需求了。
    Java提供的阻塞队列 - BlockingQueue 是一个接口, 真正实现的类是LinkedBlockingQueue我们在使用时需要new其实现类LinkedBlockingQueue的对象。

操作:

  1. put() - 用于阻塞式的入队列
  2. take() - 用于阻塞式的出队列.

    BlockingQueue也有 offer, poll, peek 等方法, 但是这些方法不带有阻塞特性,但是一般不会使用。

3. 阻塞队列的实现

    这里的阻塞是通过 “循环数组” 的方式来实现的,只需要对其操作使用 synchronized 进行加锁控制.,保证原子性,put 插入元素的时候, 判定如果队列满了, 就进行 wait.
take 取出元素的时候, 判定如果队列为空, 就进行 wait。

public class BlockingQueue {
    private int[] arr = new int[1000];
    private volatile int size = 0;
    private int front = 0;
    private int rear = 0;

    public void put(int value) throws InterruptedException {
        synchronized (this) {
            // 此处使用 while,否则 notifyAll 的时候, 该线程从 wait 中被唤醒,
            // 但是紧接着并未抢占到锁. 当锁被抢占的时候, 可能又已经队列满了
            // 就只能继续等待
            while (size == arr.length) {
                wait();
            }
            arr[rear] = value;
            rear = (rear + 1) % arr.length;
            size++;
            notifyAll();
        }
    }

    public int take() throws InterruptedException {
        int ret = 0;
        synchronized (this) {
            while (size == 0) {
                wait();
            }
            ret = arr[front];
            front = (front + 1) % arr.length;
            size--;
            notifyAll();
        }
        return ret;
    }

    public synchronized int size() {
        return size;
    }
}

    注意, 要在循环中进行 wait, 被唤醒时不一定队列就不满了/不空了, 因为同时可能是唤醒了多个线程。

4. 生产者消费者模型

    生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取.

  1. 阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力 - 削峰填谷

  2. 阻塞队列也能使生产者和消费者之间解耦.
    在这里插入图片描述
        当多个客户端(生产者)同时访问服务器时,服务器的消费能力有限,如果客户端直接将请求发送非服务器,一但超过了服务器的最大承受能力,服务器就可能会挂掉。我们可以让客户端将请求发送给阻塞队列,这样虽然不能及时返回响应但是至少保证了服务的稳定性(削峰)。同时使用这样一种模式,可以降低客户端和服务器直接的耦合,客户端的请求并不是直接到达服务器,而是经过了阻塞队列。

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

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

相关文章

CMake学习教程(一)

前言 看到陈皓大神写作的《跟我一起写 Makefile》,我也想出一个CMake学习的专栏。 距离我接触CMake已经过了3年,那是我还是研一,不懂得底层编译的事情,因为导师的项目才突然转到这个方向(项目是做工业软件的&#xf…

问题 R: 超级楼梯(递推,基础DP)查表

得到递推表达式: f(1)0,因为开始就站在第1级台阶上; f(2)1,只能从第1级台阶上1级; f(3)2,只能从第1级台阶上2级,或只能从第2级台阶上1级; f(n)f(n-2)f(n-1),n>3 …

Linux学习第25天:Linux 阻塞和非阻塞 IO 实验(二): 挂起

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 为方便和上一节的衔接,在正式开始学习前,先把本节的思维导图引入: 二、阻塞IO实验 1.硬件原理图分析 2.实验程序 #define I…

Linux两条服务器实现相互免密登录

1.准备两台虚拟机,一台充当服务器端(server),一台充当客户端(client) 服务器端(server):192.168.75.139 客户端(client):192.168.75…

腾讯云和阿里云双11优惠大战,服务器价格相差1块钱?

2023双十一优惠活动来了,同配置轻量应用服务器2核2G3M带宽,阿里云87元一年,腾讯云88元一年,阿里云不限制月流量,腾讯云限制200GB月流量,阿里云系统盘是50GB高效云盘,腾讯云是40GB SSD云硬盘&…

redis6.0源码分析:跳表skiplist

文章目录 前言什么是跳表跳表(redis实现)的空间复杂度相关定义 跳表(redis实现)相关操作创建跳表插入节点查找节点删除节点 前言 太长不看版 跳跃表是有序集合zset的底层实现之一, 除此之外它在 Redis 中没有其他应用。…

LED主流光源-高均匀条形光源

(1)产品特点: ① 高均匀条形照明光源,可制作长度最长为 2000mm 的光源; ② 可用 M3 螺纹孔安装,也可以在三个挤型槽内插入 M3 螺母安装。 (2)应用领域: ① 电子元件识别与…

掌握Python:开启未来的大门

Python,一门以其简洁性和多才多艺而著称的编程语言,正成为未来的关键技能之一。随着数字时代的到来,Python的发展前景愈发广泛,而且其易学性吸引着越来越多的学习者。 1.Python的发展前景: Python在数据科学、人工智能…

任正非说:我们要改善和媒体的关系,而不是要利用媒体,不要自以为聪明。

嗨,你好!这是华研荟【任正非说】系列的第22篇文章,让我们继续聆听任正非先生的真知灼见,学习华为的管理思想和管理理念。 一、我曾经在与一个世界著名公司,也是我司全方位的竞争对手的合作时讲过,我是拉宾的…

【数学基础】【进制转换】十进制转其他进制、其他进制转十进制

十进制转其他进制 JavaScript实现 const convert (num,base2)>{return !num?0:convert(~~(num/base),base)*10(num%base); } convert(8,2) // 1000 convert(8,8) // 10 convert(8,16) // 8其他进制转十进制 JavaScript实现 const reconvert (num,base2,curr1)>{retu…

代码随想录算法训练营第4天| 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交 、142.环形链表II

JAVA语言编写 24. 两两交换链表中的节点 谷歌、亚马逊、字节、奥多比、百度 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。…

浙大网新:重视AI驱动,就是重视未来发展

【科技明说 | 重磅专题】 对于浙大网新在AI方面的发展情况,我是看到一个消息之后才开始有了关注,之前总感觉浙大网新在AI方面战略雷声大雨点小,然而当我看到这个消息后才发现,浙大网新其实也非常重视AI方面的发展。 …

【微信小程序】WXML的模板语法与WXSS模板样式

🖥️🖥️🖥️ 博主主页: 👉🏻 👉🏻 👉🏻 糖 -O- 🚩🚩🚩微信小程序专栏:微信小程序 &…

聚量推客升级啦,加入了外卖cps、话费充值等

“聚量推客”升级啦,加入了生活cps模块,包含美团外卖cps、滴滴打车出行cps、电影票推广、话费充值等cps推广场景,聚量推客不止是app地推拉新和网推拉新平台,更是一个 综合性推广平台,未来会接入越来越多的推广场景&…

OpenCV官方教程中文版 —— Hough 直线变换

OpenCV官方教程中文版 —— Hough 直线变换 前言一、原理二、OpenCV 中的霍夫变换三、Probabilistic Hough Transform 前言 目标 • 理解霍夫变换的概念 • 学习如何在一张图片中检测直线 • 学习函数:cv2.HoughLines(),cv2.HoughLinesP() 一、原理…

基础课13——数据异常处理

数据异常是指数据不符合预期或不符合常识的情况。数据异常可能会导致数据分析结果不准确,甚至是错误,因此在进行数据分析之前需要对数据进行清洗和验证。 常见的数据异常包括缺失值、重复值、异常值等。 缺失值是指数据中存在未知值或未定义的值&#…

Winform 多语言化快速解析替换工具-1分钟一个界面

随着业务的扩展,有的软件有多语言化的需求。那么如果软件已经很多写死的文字内容如何快速进行语言化替换呢,一个一个去改工作量太大。 于是开发了个小工具用来替换现有内容并生成语音包,原理就是采用正则表达式进行匹配控件关键字以及中文进…

使用MLC-LLM将RWKV 3B模型跑在Android手机上

0x0. 前言 这篇文章主要是填一下 MLC-LLM 部署RWKV World系列模型实战(3B模型Mac M2解码可达26tokens/s) 这里留下来的坑,这篇文章里面介绍了如何使用 MLC-LLM 在A100/Mac M2上部署 RWKV 模型。但是探索在Android端部署一个RWKV对话模型的ap…

宇信科技:强势行业加速融入AIGC,同时做深做细

【科技明说 | 重磅专题】 大家可能没有想到,一向对外低调行事的宇信科技,在AIGC方面2023年就已经训练出了适配金融场景的垂直模型,并应用到了各产品线上,同时结合通用大模型预研了宇信金融系统编程大模型。宇信金融系…

IOC课程整理-15 Spring 类型转换

1. Spring 类型转换的实现 2. 使用场景 3. 基于 JavaBeans 接口的类型转换 4. Spring 內建 PropertyEditor 扩展 5. 自定义 PropertyEditor 扩展 6. Spring PropertyEditor 的设计缺陷 7. Spring 3 通用类型转换接口 8. Spring 內建类型转换器 9. Converter 接口的局限性 10. G…