ArrayBlockingQueue是线程安全、基于数组的有界阻塞队列,使用ReentrantLock和notEmpty/notFull条件队列实现生产者-消费者协调;初始化需指定固定容量,不支持null;put()和take()分别实现阻塞式入队与出队,支持超时和中断处理。

在 Java 中,ArrayBlockingQueue 是一个线程安全、基于数组实现的有界阻塞队列,天然适合构建固定容量的生产者-消费者模型。它内部使用可重入锁(ReentrantLock)和两个条件队列(notEmpty、notFull),能自动协调生产者等待空间、消费者等待元素的阻塞行为。
初始化带固定容量的 ArrayBlockingQueue
创建时必须指定容量,且不可动态扩容。建议根据业务吞吐量与内存约束合理设定——过小易频繁阻塞,过大则浪费内存或掩盖背压问题。
- 使用默认公平策略(FIFO 等待):
new ArrayBlockingQueue<String>(10) - 启用公平锁(避免线程饥饿,但性能略低):
new ArrayBlockingQueue<String>(10, true) - 不支持 null 元素,插入 null 会抛
NullPointerException
生产者:用 put() 实现阻塞式入队
put(E e) 是核心生产方法——当队列满时,当前线程会**一直阻塞**,直到有空间可用。适合对数据不丢失、强可靠性要求的场景。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 示例生产逻辑:
queue.put("task-" + i); - 若需超时控制,改用
offer(E e, long timeout, TimeUnit unit),返回false表示失败 - 避免在持有其他锁时调用
put(),以防死锁
消费者:用 take() 实现阻塞式出队
take() 与 put() 对应——当队列为空时,线程**主动挂起等待**,直到有新元素到达。这是最简洁的“拉取即处理”模式。
立即学习“Java免费学习笔记(深入)”;
- 典型消费循环:
String task = queue.take(); process(task); - 如需非阻塞或带超时,可用
poll()或poll(long, TimeUnit) - 注意:中断正在
take()的线程会抛InterruptedException,需正确处理并恢复中断状态
完整协作示例(含异常与关闭逻辑)
真实场景中,生产者可能结束,消费者需感知并退出。推荐配合 Thread.interrupt() 和中断检查实现优雅终止。
- 生产者完成时调用
queue.put(POISON_PILL)(自定义结束标记),消费者收到后 break - 或用
AtomicBoolean running = new AtomicBoolean(true)控制循环,配合Thread.currentThread().isInterrupted() - 避免在 finally 块中调用
clear()—— 可能破坏正在并发操作的队列一致性

















