什么是阻塞队列?
阻塞队列(Blocking Queue)是 Java 并发包(java.util.concurrent
)中的一种线程安全队列,支持以下两种附加操作:
- 阻塞插入:当队列满时,生产者线程会被阻塞,直到队列有空闲位置。
- 阻塞移除:当队列空时,消费者线程会被阻塞,直到队列有元素可用。
其核心作用是协调生产者和消费者的执行速度,避免资源竞争和数据不一致问题。
Java 中常见的阻塞队列实现
实现类 | 特点 |
---|---|
ArrayBlockingQueue | 基于数组的有界队列,FIFO 顺序,需指定初始容量。 |
LinkedBlockingQueue | 基于链表的可选有界/无界队列(默认无界,容量为 Integer.MAX_VALUE ),吞吐量较高。 |
PriorityBlockingQueue | 支持优先级排序的无界队列,元素需实现 Comparable 接口。 |
DelayQueue | 无界队列,元素需实现 Delayed 接口,延迟到期后才能被取出(适用于定时任务)。 |
SynchronousQueue | 无容量队列,每个插入操作必须等待对应的移除操作(直接传递数据)。 |
LinkedTransferQueue | 无界队列,支持高效的“匹配”操作(如 transfer() ,生产者等待消费者取走元素)。 |
有界队列 vs 无界队列
对比维度 | 有界队列 | 无界队列 |
---|---|---|
容量限制 | 固定容量,初始化时指定(如 ArrayBlockingQueue )。 | 理论容量无限(如 LinkedBlockingQueue 默认)。 |
资源控制 | 避免内存溢出,适合生产速度不可控的场景。 | 无容量限制,可能因生产过快导致内存溢出(需谨慎使用)。 |
阻塞场景 | 队列满时阻塞生产者线程。 | 队列永远不会满,生产者线程不会被阻塞。 |
适用场景 | 需要严格限制资源使用的场景(如高并发系统)。 | 生产速度可控且消费速度较快的场景(如日志缓冲)。 |
典型应用场景
线程池任务队列:
- 有界队列(如
ArrayBlockingQueue
)用于控制任务积压,避免内存溢出。 - 无界队列(如
LinkedBlockingQueue
)用于任务处理速度较快的场景。
- 有界队列(如
生产者-消费者模型:
- 使用
LinkedBlockingQueue
解耦生产者和消费者,平衡处理速度差异。
- 使用
延迟任务调度:
- 使用
DelayQueue
实现定时任务执行(如订单超时取消)。
- 使用
优先级任务处理:
- 使用
PriorityBlockingQueue
按优先级处理任务(如 VIP 用户请求优先处理)。
- 使用
总结
- 有界队列适合资源敏感型场景,通过容量限制保护系统稳定性。
- 无界队列适合生产速度可控的场景,但需警惕内存溢出风险。
- 实现选择需结合具体需求:顺序性、优先级、延迟特性等。
- 经典组合:线程池(如
ThreadPoolExecutor
)通常搭配有界队列或SynchronousQueue
实现高效任务调度。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。