什么叫做阻塞队列的有界和无界
在 Java 并发编程中,阻塞队列(BlockingQueue) 是线程安全的队列,可以在队列为空时自动阻塞消费者线程,或在队列满时自动阻塞生产者线程。
阻塞队列根据容量限制,分为:
一、有界阻塞队列(Bounded BlockingQueue)
定义:
有界队列是指在创建时指定了最大容量上限,一旦队列满了,继续 put() 或 offer() 操作将阻塞或返回失败。
示例:
BlockingQueue<String> queue = new ArrayBlockingQueue<>(3);
队列最大只能存储 3 个元素:
queue.put("a");
queue.put("b");
queue.put("c");
// 下面这行将阻塞,直到有空间
queue.put("d");
适用场景:
- 生产速度高于消费速度时控制内存使用
- 防止任务无限堆积(防止 OOM)
- 典型用于线程池中的任务队列(默认使用
LinkedBlockingQueue(capacity))
二、无界阻塞队列(Unbounded BlockingQueue)
定义:
无界队列是指理论上没有容量上限,可以无限添加元素,除非系统内存耗尽。
实际实现中,有一个非常大的
Integer.MAX_VALUE作为容量上限,但不会主动阻塞生产者。
示例:
BlockingQueue<String> queue = new LinkedBlockingQueue<>();
添加数据时不会阻塞:
queue.put("a"); // 永远不会阻塞
⚠️ 风险提示:
- 如果生产速度远大于消费速度,任务会不断堆积,占用大量内存
- 极端情况下可能导致 OOM(OutOfMemoryError)
三、有界 vs 无界 对比总结
| 特性 | 有界队列 | 无界队列 |
|---|---|---|
| 容量限制 | 有固定上限 | 理论无限(上限为 Integer.MAX) |
| 队列满时行为 | put() 阻塞,offer() 返回 false | 永远不会阻塞 |
| 内存安全性 | ✅ 控制内存使用 | ❌ 有 OOM 风险 |
| 用于线程池任务队列 | 推荐使用(如 ThreadPoolExecutor) | 不推荐(可能导致线程无法扩展) |
| 常见实现类 | ArrayBlockingQueue, LinkedBlockingQueue(capacity) | LinkedBlockingQueue()(无参数) |
四、线程池中的典型用法
ExecutorService pool = new ThreadPoolExecutor(
2, 4,
60L, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(100) // ✅ 有界阻塞队列
);
- 当任务队列满时,线程池会拒绝新任务(可配置拒绝策略)
- 如果使用无界队列,线程池永远不会扩展线程,只靠队列堆积任务(不推荐)
📘 参考资料
- 🔗 Java 官方文档:BlockingQueue
- 🔗 Java 官方文档:ArrayBlockingQueue
- 🔗 Java 官方文档:LinkedBlockingQueue
- 美团技术博客:线程池任务队列原理
更多详细内容请关注其他相关文章!