当前位置: 首页 > backend >正文

Java中的阻塞队列有界和无界区别

在Java中,阻塞队列(Blocking Queue)是一个线程安全的队列,它能够在队列为空时使消费者线程阻塞,或者在队列满时使生产者线程阻塞。阻塞队列在并发编程中非常常见,特别是在生产者-消费者问题的场景中。

阻塞队列可以分为有界阻塞队列无界阻塞队列

1. 有界阻塞队列(Bounded Blocking Queue)

有界阻塞队列是指队列的大小是有限制的。当队列已满时,生产者线程会被阻塞,直到队列中有空间可以插入新元素为止。同样,当队列为空时,消费者线程会被阻塞,直到队列中有新元素可供消费。

使用场景:
  • 任务队列:在有并发消费者时,队列大小有限制,以防止内存溢出。
  • 流控:通过限制队列的大小来防止生产者过快地生成任务,导致资源消耗过大。
代码示例:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;public class BoundedBlockingQueueExample {public static void main(String[] args) throws InterruptedException {// 创建一个有界阻塞队列,容量为5BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(5);// 生产者线程Thread producer = new Thread(() -> {try {for (int i = 0; i < 10; i++) {queue.put(i); // 如果队列满了,生产者会被阻塞System.out.println("Produced: " + i);}} catch (InterruptedException e) {Thread.currentThread().interrupt();}});// 消费者线程Thread consumer = new Thread(() -> {try {for (int i = 0; i < 10; i++) {Integer item = queue.take(); // 如果队列为空,消费者会被阻塞System.out.println("Consumed: " + item);}} catch (InterruptedException e) {Thread.currentThread().interrupt();}});producer.start();consumer.start();producer.join();consumer.join();}
}
解释:
  • ArrayBlockingQueue 是一个典型的有界阻塞队列,容量为 5。
  • 生产者线程会在队列满时被阻塞,消费者线程会在队列为空时被阻塞。

2. 无界阻塞队列(Unbounded Blocking Queue)

无界阻塞队列是指队列的大小没有限制,理论上可以容纳无限个元素。在无界阻塞队列中,生产者不会因为队列已满而被阻塞,而是会一直将元素放入队列中;同样,消费者也不会因为队列为空而被阻塞(虽然通常会等待有新的元素可供消费)。

使用场景:
  • 不需要流控:当生产者生成数据的速度远慢于消费者时,队列大小无所谓。
  • 动态扩展:当队列的大小没有明确限制时,可以适应生产者和消费者之间不平衡的情况。
代码示例:
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.BlockingQueue;public class UnboundedBlockingQueueExample {public static void main(String[] args) throws InterruptedException {// 创建一个无界阻塞队列BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();// 生产者线程Thread producer = new Thread(() -> {try {for (int i = 0; i < 10; i++) {queue.put(i); // 不会被阻塞,因为队列是无界的System.out.println("Produced: " + i);}} catch (InterruptedException e) {Thread.currentThread().interrupt();}});// 消费者线程Thread consumer = new Thread(() -> {try {for (int i = 0; i < 10; i++) {Integer item = queue.take(); // 如果队列为空,消费者会被阻塞System.out.println("Consumed: " + item);}} catch (InterruptedException e) {Thread.currentThread().interrupt();}});producer.start();consumer.start();producer.join();consumer.join();}
}
解释:
  • LinkedBlockingQueue 是一个典型的无界阻塞队列。
  • 由于是无界的,生产者不会因为队列满而被阻塞,消费者会等到有新的元素可供消费。

有界与无界阻塞队列的比较

特性有界阻塞队列无界阻塞队列
队列大小有限无限(理论上没有大小限制)
生产者行为队列满时,生产者会被阻塞队列大小不受限制,生产者不会阻塞
消费者行为队列空时,消费者会被阻塞队列为空时,消费者会被阻塞
内存使用队列大小受限,避免内存溢出内存可能被用尽,造成资源消耗过大
典型应用场景任务队列、流控、资源管理数据传输、生产者消费者模型(当生产者慢于消费者时)

总结:

  • 有界阻塞队列适用于资源有限的情况,它能帮助限制队列的大小,防止内存溢出并进行流控。
  • 无界阻塞队列适用于队列容量不受限制的情况,但要注意如果生产者速度过快,可能会导致系统资源消耗过大。

根据实际应用场景选择适合的阻塞队列类型。

http://www.xdnf.cn/news/1633.html

相关文章:

  • Langchain检索YouTube字幕
  • Axure复选框组件的深度定制:实现自定义大小、颜色与全选功能
  • react-09React生命周期
  • 解析塔能科技:绿色低碳智慧节能一站式破局之匙
  • 极狐GitLab 如何从 CSV 导入议题?
  • 实时步数统计系统 kafka + spark +redis
  • 4.1 融合架构设计:LLM与Agent的协同工作模型
  • 遨游三防|30200mAh、双露营灯三防平板,见证堆料天花板
  • 多语言笔记系列:使用用户输入
  • Python爬虫爬取图片并存储到MongoDB(注意:仅尝试存储一条空的示例数据到MongoDB,验证MongoDB的联通性)
  • 220V转18V600mA非隔离芯片WT5110
  • 【防火墙 pfsense】1简介
  • Freerots----任务通知
  • Qt本地化 - installTranslator不生效
  • Atlas 800I A2 离线部署 DeepSeek-R1-Distill-Llama-70B
  • 2025年土建施工员考试题库及答案
  • Control Center安卓版:自定义控制中心,提升手机操作体验
  • PostgreSQL 分区表——范围分区SQL实践
  • 【金仓数据库征文】——金仓数据库:国产数据库的卓越之选
  • Docker-高级使用
  • 反射,枚举,lambda表达式
  • 网页版 deepseek 对话问答内容导出为 PDF 文件和 Word 文件的浏览器插件下载安装和使用说明
  • 【axios取消请求】如何在token过期后取消未响应的请求
  • 针对密码学的 EM 侧信道攻击
  • git 操作
  • Golang编程拒绝类型不安全
  • 嵌入式人工智能应用-第三章 opencv操作8 图像特征之 Haar 特征
  • springboot整合redis实现缓存
  • 协作开发攻略:Git全面使用指南 — 第二部分 高级技巧与最佳实践
  • 无标注文本的行业划分(行业分类)算法 —— 无监督或自监督学习