arrayblockingqueue是java中基于数组实现的线程安全、有界阻塞队列,容量固定且支持公平/非公平策略;提供add/offer/put和poll/take/poll(timeout)四类操作,适用于生产者-消费者模型限流控压。

ArrayBlockingQueue 是 Java 并发包(java.util.concurrent)中提供的线程安全、有界阻塞队列,底层基于数组实现,适合在生产者-消费者模型中控制资源上限、避免内存溢出。
创建与基本使用
必须指定容量大小,且容量不可变。支持可选的公平性策略(默认非公平):
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
-
// 创建容量为 10 的阻塞队列,非公平模式(推荐,默认)
ArrayBlockingQueuequeue = new ArrayBlockingQueue(10); -
// 创建公平队列:等待时间长的线程优先获取锁(吞吐量略低,但更可预测)
ArrayBlockingQueuefairQueue = new ArrayBlockingQueue(10, true);
核心操作方法与线程安全语义
所有操作天然线程安全,无需额外同步。注意区分四类行为风格(抛异常 / 返回特殊值 / 阻塞 / 超时):
-
add(e):成功返回 true;队列满时抛
IllegalStateException - offer(e):成功返回 true;队列满时返回 false(推荐用于非阻塞判断)
- put(e):阻塞直到有空位(生产者典型用法)
- poll():立即取头元素,为空时返回 null
- take():阻塞直到有元素可取(消费者典型用法)
- poll(timeout, unit):超时等待获取元素,避免无限阻塞
典型生产者-消费者场景示例
两个线程协作,通过 ArrayBlockingQueue 解耦并限流:
-
// 生产者:每秒生成一条消息,满则等待
new Thread(() -> {
for (int i = 0; i try {
queue.put("msg-" + i);
System.out.println("Produced: msg-" + i);
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}).start(); -
// 消费者:持续取数据处理,空则等待
new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
String msg = queue.take();
System.out.println("Consumed: " + msg);
TimeUnit.MILLISECONDS.sleep(500); // 模拟处理耗时
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}).start();
注意事项与最佳实践
- 容量需根据内存和业务压力合理设置,过小易频繁阻塞,过大失去限流意义
- 避免在循环中使用
add()或remove()—— 它们不保证线程安全的批量操作,应改用offer()/poll()或put()/take() - 构造时传入的
Collection参数(如new ArrayBlockingQueue(10, false, Arrays.asList("a","b")))仅用于初始化,后续仍受容量限制 - 内部使用单个
ReentrantLock和两个Condition(notFull / notEmpty),因此是“全队列一把锁”,高并发下吞吐量低于ConcurrentLinkedQueue等无锁结构,但胜在可控与简单
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










