news 2026/4/27 1:43:30

阻塞队列的使用和实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
阻塞队列的使用和实现

阻塞队列是一种特殊的队列,其遵循“先入先出”的原则。

阻塞队列也是一种线程安全的数据结构,具有以下特性:

  • 队列为满,入队列产生阻塞,直至其他线程从队列中取走元素
  • 队列为空,出队列产生阻塞,直至其他线程往队列中插入元素

“生产者消费者模型”是阻塞队列的一个典型应用场景,该模型也是一个典型的开发模型。

生产者消费者模型

生产者消费者模型就是通过一个中间容器来解决生产者和消费者之间的强耦合问题。

这个中间容器通过阻塞队列实现,从而使生产者和消费者之间不进行直接通讯。

阻塞队列的作用:

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

阻塞队列的缺点:

  1. 引入队列以后,代码整体结构变复杂
  2. 程序执行效率有所影响

阻塞队列的使用

Java的标准库中,提供了现成的阻塞队列。

  • BlockingQueue是一个接口,真正实现的类有:LinkedBlockingQueue(链表实现),ArrayBlockingQueue(数组实现),PriorityBlockingQueue(堆实现)等等。
  • 队列的出操作是poll,入队列操作是offer,但是阻塞队列使用的分别时take和put,这两个方法是带有阻塞功能的出入队列操作。
public class demo1 { public static void main(String[] args) { //创建阻塞队列 BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(1000); //生产者线程 Thread producer = new Thread(() -> { int n = 0; while (true) { try { queue.put(n); System.out.println("生产元素 " + n); n++; } catch (InterruptedException e) { throw new RuntimeException(e); } } }, "procducer"); //消费者线程 Thread consumer = new Thread(() -> { while(true){ try { int n = queue.take(); System.out.println("消费元素 " + n); } catch (InterruptedException e) { throw new RuntimeException(e); } } }, "consumer"); producer.start(); consumer.start(); } }

阻塞队列的简单实现

  • 使用“循环队列”实现
  • 使用synchronized加锁保证线程安全
  • 注意这里的wait()搭配while使用,而不能搭配if使用,是由于notifyAll会将所有的wait唤醒,只有其中一个线程会put,而等到其他被唤醒的线程拿到锁之后,还需要确认一下容量是否已满,满的话还需要阻塞等待。
class BlockingQueue { private int[] item = new int[1000]; private volatile int head = 0; private volatile int tail = 0; private volatile int size = 0; //生产元素 public void put(int value) throws InterruptedException { synchronized (this) { while (size == item.length) { this.wait(); } item[tail] = value; tail++; if (tail == item.length) { tail = 0; } size++; notifyAll(); } } //消费元素 public int take() throws InterruptedException { synchronized (this) { while (size == 0) { this.wait(); } int ret = item[head]; head++; if(head == item.length){ head = 0; } size--; notifyAll(); return ret; } } //获取内部属性 public synchronized int getSize() { return size; } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/25 14:41:30

PatreonDownloader终极指南:快速备份创作者专属内容

你是否曾经为无法保存喜爱的Patreon创作者发布的独家内容而烦恼&#xff1f;想要一键收藏那些珍贵的图片、视频和文档&#xff0c;却苦于没有合适的工具&#xff1f;PatreonDownloader正是为解决这一痛点而生的强大下载工具&#xff0c;让你轻松备份所有创作者分享的内容。 【免…

作者头像 李华
网站建设 2026/4/20 12:30:52

如何快速掌握image2cpp:图像转字节数组的终极指南

如何快速掌握image2cpp&#xff1a;图像转字节数组的终极指南 【免费下载链接】image2cpp 项目地址: https://gitcode.com/gh_mirrors/im/image2cpp image2cpp是一款专为嵌入式系统开发者设计的在线工具&#xff0c;能够将普通图像文件转换为字节数组格式&#xff0c;或…

作者头像 李华
网站建设 2026/4/24 7:40:47

vh6501测试busoff过程中CAN收发器行为解析

深入解析 vh6501 测试 Bus-Off 过程中 CAN 收发器的真实行为在汽车电子开发的日常调试中&#xff0c;总线异常并不可怕&#xff0c;真正考验系统鲁棒性的是——当一个节点“失控”时&#xff0c;它是否会拖垮整个网络。而Bus-Off&#xff0c;正是 CAN 协议为防止这种灾难设计的…

作者头像 李华
网站建设 2026/4/23 12:54:17

python情感分类系统 深度学习 细粒度情感分类预测 Flask框架 PaddleHub 计算机 数据集OCEMOTION 毕业设计(建议收藏)

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ > &#x1f345;想要获取完整文章或者源码&#xff0c;或者代做&#xff0c;拉到文章底部即可与…

作者头像 李华
网站建设 2026/4/26 13:08:41

Arduino IDE语言选项修改深度剖析步骤

手把手教你修改 Arduino IDE 语言设置&#xff1a;从英文到中文的底层逻辑与实战你是不是刚打开 Arduino IDE&#xff0c;面对满屏英文菜单一头雾水&#xff1f;“Sketch”是啥&#xff1f;“Upload”又是哪个按钮&#xff1f;别急——这其实是每个中文初学者都会遇到的“第一道…

作者头像 李华
网站建设 2026/4/17 16:27:48

如何挑战自己的分析,避免他人挑战

原文&#xff1a;towardsdatascience.com/how-to-challenge-your-own-analysis-so-others-wont-b3745919d098?sourcecollection_archive---------2-----------------------#2024-07-03 掌握合理性检查的艺术&#xff0c;提升你的工作质量 https://medium.com/twalbaum?sourc…

作者头像 李华