blockingqueue 实现生产者消费者模型的核心是利用其内置线程安全与阻塞语义,无需手动加锁或 wait/notify;put() 在队列满时阻塞,take() 在队列空时阻塞,offer/poll 支持超时或非阻塞操作,arrayblockingqueue(有界)和 linkedblockingqueue(可选有界)是常用实现。

用 BlockingQueue 实现生产者消费者模型,核心是把线程间的数据传递和同步逻辑交给队列本身处理,不用手动加锁、wait/notify 或条件变量。
直接用 offer/put + poll/take 就能避免阻塞和竞态
BlockingQueue 的关键方法自带线程安全和阻塞语义:
-
put(e):队列满时自动阻塞,直到有空间;适合“必须存进去”的场景 -
take():队列空时自动阻塞,直到有元素;适合“必须取一个”的场景 -
offer(e, timeout, unit)和poll(timeout, unit):带超时的非永久阻塞,防止无限等待 -
offer(e)和poll():不阻塞,失败立即返回false或null,适合需要快速响应的逻辑
一个典型实现:用 LinkedBlockingQueue 启动多生产者多消费者
选 LinkedBlockingQueue(无界)或 ArrayBlockingQueue(有界)即可,不需要额外同步:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
BlockingQueue<string> queue = new LinkedBlockingQueue(1000);
// 生产者
new Thread(() -> {
for (int i = 0; i {
while (true) {
try {
String item = queue.take(); // 自动阻塞等待数据
System.out.println("Consumed: " + item);
if ("item-99".equals(item)) break; // 简单退出条件
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}).start();
</string>
注意 shutdown 和中断处理的惯用写法
真实项目中不能靠 while(true) + break 控制生命周期,建议配合 Thread.interrupt():
- 消费者用
poll(timeout, unit)替代take(),在循环中检查Thread.currentThread().isInterrupted() - 生产者完成任务后调用
queue.offer(END_SIGNAL),消费者收到信号后主动退出 - 所有线程启动后,可用
ExecutorService统一管理,调用shutdown()+awaitTermination()
为什么比手写 wait/notify 更可靠
手写容易出错的地方,BlockingQueue 全部封装好了:
- 不需要显式
synchronized块,内部已保证操作原子性 - 不会漏唤醒或虚假唤醒——
take()和put()内部用Condition精确控制等待队列 - 容量控制天然支持背压(backpressure),比如
ArrayBlockingQueue(10)能让生产者在积压到 10 条时自动停顿 - 所有异常(如中断)都通过标准的
InterruptedException抛出,符合 Java 并发规范
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










