← ReJava · 学习目录

REJAVA / LEARNING NOTES

第7课速查:BlockingQueue(阻塞队列)

随时回查术语、规则和示例;完整解释见对应课程。

Java 17 / 21更新于 2026.10.12约 3 分钟阅读

根据课程材料整理

本次更新说明
  • 页尾去掉本地资料入口。
  • 整理为公开学习笔记,保留技术内容与练习。

1 · 是什么

线程安全队列,多了等待:队满时放入方等空位,队空时取出方等元素。主要用于生产者-消费者。

放入之前的操作 happens-before(先行发生关系) 取出之后的操作。

回看

2 · 四组方法

抛异常特殊值一直等等一会
放add(追加方法)offer(尝试放入方法)→falseput(写入方法)offer(e,t,u)
取removepoll(尝试取出方法)→null(空值)take(阻塞取出方法)poll(t,u)
看elementpeek——

请求线程用 offer(尝试放入方法);后台消费用 take(阻塞取出方法)。不收 null(空值)。等待被中断抛 InterruptedException(中断异常),标记已清除,catch 里 Thread.currentThread().interrupt()。

回看

3 · 常用实现

ArrayBlockingQueue(数组阻塞队列): 数组,必须指定容量,一把锁。

LinkedBlockingQueue(链式阻塞队列): 链表,容量可选,不传=Integer.MAX_VALUE(整数类型最大值),两把锁;官方:吞吐通常更高、性能更难预测。 一定传容量。

SynchronousQueue(同步移交队列): 容量 0,一手交一手(newCachedThreadPool)。

PriorityBlockingQueue(优先级阻塞队列) 按优先级、 DelayQueue(延迟队列) 到期才取,均无界。

回看

4 · 内部怎么等

ReentrantLock(可重入锁)+Condition(条件等待室)。await 放开锁去睡,signal 叫醒,醒来要重新拿锁。

数组版: 一把锁+notFull/notEmpty;while (count == items.length) notFull.await();。while 防虚假唤醒。

链表版: putLock 管尾、takeLock 管头,元素个数用 AtomicInteger(原子整数类);从空变非空才叫醒取出方(连锁唤醒)。

回看

5 · 有界与线程池

newFixedThreadPool=无容量 LinkedBlockingQueue(链式阻塞队列) → 任务堆积耗尽内存,最大线程数失效。newCachedThreadPool=SynchronousQueue(同步移交队列)+最大线程数无上限。

生产用 ThreadPoolExecutor(线程池执行器)+有界队列;队满 offer(尝试放入方法) 失败或超时,把压力传回上游(背压)。容量 ≈ 每秒处理量 × 可接受等待秒数,再压测。

回看

6 · 手写生产者-消费者

有界队列;生产者 put(写入方法)、消费者 take(阻塞取出方法),不自己 sleep 轮询;生产者最后放结束标记,消费者取到就 break(跳出循环语句); 几个消费者就放几个标记 ;catch 中断后恢复标记。

局限:队列在进程内存里,重启会丢、多实例不共享 → 需要时用消息队列。

回看

返回完整课程 · 检验 · 官方依据与源码 · 课程目录