ArrayBlockingQueue 是线程安全、有界、基于数组的阻塞队列,适用于单机生产者-消费者模型;需合理设置容量(2~5倍峰值批次)、选用公平模式、搭配 put/take 或带超时的 offer/poll,并做好生命周期管理与异常处理。

ArrayBlockingQueue 是 Java 并发包中一个线程安全、有界、基于数组实现的阻塞队列,特别适合在单机环境下构建简单可靠的生产者-消费者模型。它天然支持阻塞操作(put/take),无需额外加锁或等待逻辑,是轻量级解耦的首选。
初始化合适的容量和线程模型
容量决定缓冲能力,也影响吞吐与响应平衡。太小容易频繁阻塞,太大可能掩盖处理瓶颈或占用过多内存。建议根据业务吞吐预估峰值每秒生产/消费量,设置为 2~5 倍的典型批次大小(例如:预估单秒最多生成 100 条,可设容量为 200~500)。
- 使用公平模式(fair = true)可避免线程饥饿,尤其当消费者线程数多于生产者时更稳妥
- 通常配 1 个或少数几个生产者线程 + 多个消费者线程(如 CPU 核心数 × 1.5),避免消费者成为瓶颈
- 示例初始化:new ArrayBlockingQueue<String>(256, true)
生产者端用 put 或 offer 配合策略选择
put() 会阻塞直到有空位,适合对实时性要求不高、允许短暂等待的场景;offer(E, timeout, unit) 可设超时,适合需要快速失败或降级的业务(如日志采集不能卡住主流程)。
- 若生产速度远高于消费,长期阻塞 put 可能拖慢上游,此时优先用带超时的 offer
- 捕获 InterruptedException 并合理处理(如恢复中断状态、记录告警、退出循环)
- 避免在循环内反复 try-catch 异常却不退出,防止无限重试压垮队列
消费者端用 take 或 poll 保持主动与韧性
take() 阻塞获取元素,适合稳定消费场景;poll(timeout, unit) 更灵活,可用于实现“空闲时休眠+唤醒”或配合定时任务做批量处理。
- 推荐用 while 循环 + take(),简洁且语义清晰(只要队列没关闭就持续取)
- 若需优雅关闭,可用 poll(100, TimeUnit.MILLISECONDS) 替代 take(),方便检测 shutdown 信号
- 消费逻辑务必包裹 try-catch,防止单条异常导致整个消费者线程退出
注意生命周期管理与资源释放
ArrayBlockingQueue 本身无 close 方法,但生产者/消费者线程需协调终止。常见做法是用 volatile boolean 标记运行状态,并结合 interrupt() 中断等待中的线程。
- 生产者检测到关闭信号后,应停止提交新任务,并等待队列变空或超时后退出
- 消费者收到中断后,应处理完当前已取出的元素,再退出循环
- 可借助 CountDownLatch 或 CyclicBarrier 等同步工具等待所有消费者完成最后一批处理

















