ArrayBlockingQueue是Java并发包中基于数组、线程安全、有界且遵循FIFO的阻塞队列,容量固定不可变,支持公平/非公平模式,提供put/take等阻塞操作,适用于生产者-消费者场景。

ArrayBlockingQueue 是 Java 并发包(java.util.concurrent)中提供的一个线程安全、基于数组实现的有界阻塞队列。它遵循 FIFO(先进先出)原则,容量在创建时固定,无法动态扩容;当队列满时,插入操作会阻塞;当队列空时,获取操作会阻塞。
创建和基本使用
必须指定容量(正整数),可选是否启用公平策略(默认非公平):
-
new ArrayBlockingQueue<string>(10)</string>:容量为 10 的非公平队列 -
new ArrayBlockingQueue<integer>(5, true)</integer>:容量为 5 的公平队列(等待时间长的线程优先获取锁)
注意:容量为 0 会抛 IllegalArgumentException;公平模式性能略低但能减少线程饥饿。
常用阻塞操作方法
核心是四个带阻塞语义的方法,适合生产者-消费者场景:
-
put(E e):插入元素,队列满时阻塞,直到有空间 -
take():取出并移除头元素,队列空时阻塞,直到有元素 -
offer(E e, long timeout, TimeUnit unit):带超时的插入,超时返回false -
poll(long timeout, TimeUnit unit):带超时的取出,超时返回null
对比非阻塞方法(如 offer()、poll())——它们失败立即返回 false 或 null,不挂起线程。
典型生产者-消费者示例
用两个线程模拟:生产者每秒放一个数字,消费者每两秒取一个:
- 定义队列:
ArrayBlockingQueue<integer> queue = new ArrayBlockingQueue(3);</integer> - 生产者调用
queue.put(i),若队列已满(比如 3 个元素),该线程暂停,直到消费者取走至少一个 - 消费者调用
queue.take(),若队列为空,线程等待,直到生产者放入新元素
无需额外同步或 wait/notify,所有线程安全性由内部锁和条件队列保证。
注意事项和限制
它不是无界队列,不能像 LinkedBlockingQueue 那样指定 Integer.MAX_VALUE 模拟无界;容量不可变,初始化后无法调整。遍历(如 for-each)不会加锁,可能看到“瞬时快照”,不保证实时一致性。若需高吞吐且容量可变,应考虑其他队列;若强调确定性容量与简单性,ArrayBlockingQueue 是可靠选择。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











