blockingqueue 是 java 并发包中线程安全的阻塞队列,支持生产者-消费者模型;常用实现包括 arrayblockingqueue(有界数组)、linkedblockingqueue(高吞吐链表)、synchronousqueue(直接交接)和 priorityblockingqueue(优先级排序)。

BlockingQueue 是 Java 并发包(java.util.concurrent)中专为线程安全设计的阻塞队列,天然支持多线程间的异步通信:生产者线程往队列里放数据,消费者线程从队列取数据;当队列满时生产者自动阻塞,空时消费者自动等待,无需手动加锁或 wait/notify。
选择合适的 BlockingQueue 实现类
不同场景适用不同实现:
- ArrayBlockingQueue:基于数组、有界队列,创建时必须指定容量,适合对内存使用敏感、需严格控制队列大小的场景。
- LinkedBlockingQueue:基于链表,默认无界(实际是 Integer.MAX_VALUE),吞吐量高,适合大多数通用异步任务传递(如日志收集、消息分发)。
- SynchronousQueue:不存储元素,每个插入操作必须等待另一个线程的移除操作,适合“直接交接”式通信(类似线程间手递手传对象)。
- PriorityBlockingQueue:支持优先级排序的无界队列,适用于需要按优先级处理任务的场景(如告警分级处理)。
用法核心:生产者-消费者模型
典型模式是启动多个生产者线程调用 put() 或 offer(),多个消费者线程调用 take() 或 poll()。关键点:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
-
put(e)和take()是阻塞方法:队列满时put挂起,空时take挂起,直到条件满足。 -
offer(e, timeout, unit)和poll(timeout, unit)支持超时,避免无限等待,适合有响应时间要求的系统。 - 所有操作线程安全,内部已做同步,无需额外 synchronized。
一个完整可运行示例
模拟订单处理系统:订单生成线程(生产者)向队列添加订单,处理线程(消费者)从中取出并打印:
<font size="2"><pre class="brush:php;toolbar:false;">// 创建容量为 10 的阻塞队列<br>BlockingQueue<string> orderQueue = new ArrayBlockingQueue(10);<br><br>// 生产者线程<br>new Thread(() -> {<br> for (int i = 1; i try {<br> String order = "ORDER-" + i;<br> System.out.println("生产:" + order);<br> orderQueue.put(order); // 阻塞直到入队成功<br> Thread.sleep(200);<br> } catch (InterruptedException e) {<br> Thread.currentThread().interrupt();<br> }<br> }<br>}).start();<br><br>// 消费者线程<br>new Thread(() -> {<br> for (int i = 0; i try {<br> String order = orderQueue.take(); // 阻塞直到取到元素<br> System.out.println("消费:" + order);<br> Thread.sleep(300);<br> } catch (InterruptedException e) {<br> Thread.currentThread().interrupt();<br> }<br> }<br>}).start();</string>
注意事项与最佳实践
实际使用中容易忽略但影响稳定性的问题:
- 务必捕获
InterruptedException并恢复中断状态(Thread.currentThread().interrupt()),否则上层无法感知中断意图。 - 避免在循环中频繁调用无参
poll()或peek()—— 它们不阻塞,会变成忙等,浪费 CPU。 - 若队列用于任务分发,建议配合
ThreadPoolExecutor使用其内置的BlockingQueue(如new ThreadPoolExecutor(..., new LinkedBlockingQueue())),更符合线程池语义。 - 注意内存泄漏风险:如果队列长期堆积未消费的对象(尤其含大对象或引用外部上下文),需监控队列 size 并设置合理超时或拒绝策略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










