面试高频!ArrayBlockingQueue vs LinkedBlockingQueue,99%的人答不全!

80 阅读4分钟



小米最近在刷社招面试题,发现“ArrayBlockingQueue 和 LinkedBlockingQueue 的区别”频繁出现在面试官的题库里。

作为一名喜欢分享技术的 31 岁“老程序员”,小米觉得有必要深挖一波,顺便给大家讲讲这两位 Java 并发容器中的明星选手。毕竟,光会 API 可不够,面试官喜欢追着问底层原理!

好了,故事开始了!

起源:为什么需要阻塞队列?

某一天,小米在公司加班,产品经理老王突然跑来:“小米,我们的任务队列经常出错,你看看咋回事?”

小米打开日志一看,原来是有些线程在消费任务的时候队列为空,导致 NullPointerException,而生产者又可能突然暴增,导致 OutOfMemoryError

于是,小米一拍脑袋:“这就是典型的生产者-消费者问题,用阻塞队列就能解决!

阻塞队列的作用:

  • 生产者-消费者模型:生产者不断往队列里放数据,消费者不断从队列取数据,生产快了队列会阻塞生产者,消费慢了队列会阻塞消费者,保证了流量的平稳。
  • 线程间通信:不需要使用 synchronized 和 wait/notify,内部已经封装好了锁机制,简化多线程编程。
  • 防止过载:队列可以设置容量上限,防止生产过快导致 OOM。

java.util.concurrent 包里提供了多个阻塞队列,今天我们重点讲解ArrayBlockingQueueLinkedBlockingQueue,它们是面试中最常考的两位“老大哥”。

ArrayBlockingQueue:数组实现的有界队列

基本特点:

  • 基于数组,底层是 Object[],容量固定(有界队列)。
  • FIFO(先进先出) ,头部取数据,尾部插入数据。
  • 数据结构简单,内存占用低,适合高性能场景。
  • 单一 ReentrantLock 进行并发控制,锁粒度大,生产和消费不能同时进行。

源码解析:

ArrayBlockingQueue 面试核心点

  • 容量固定,创建时必须指定大小,不能动态扩容。
  • 性能较高,但由于采用单一锁,并发能力稍差
  • 数据存放在数组中,适合元素数量稳定的场景,避免频繁扩容带来的开销。

LinkedBlockingQueue:链表实现的有界/无界队列

基本特点:

  • 基于链表,底层是 Node 链表,可以是有界队列(指定大小)或无界队列(默认 Integer.MAX_VALUE)
  • FIFO(先进先出) ,头部取数据,尾部插入数据。
  • 双锁机制,生产和消费使用不同的 ReentrantLock,并发能力更强。
  • 适合吞吐量要求较高的场景,但链表结构可能增加 GC 压力

源码解析:

LinkedBlockingQueue 面试核心点

  • 默认无界,但可以指定大小,防止 OOM。
  • 性能更高,采用双锁机制,生产者和消费者可以并行执行
  • 数据存放在链表中,适合元素数量不确定的场景,但链表结构可能增加内存开销和 GC 压力。

场景对比:哪种更适合你的项目?

总结选择指南:

  • 数据量稳定,低延迟需求,选 ArrayBlockingQueue(如高频交易系统)。
  • 数据量不确定,吞吐量高,选 LinkedBlockingQueue(如日志收集、任务队列)。
  • 避免无界 LinkedBlockingQueue,否则可能导致 OOM。

面试真题实战

面试题 1:你会怎么选择 ArrayBlockingQueue 和 LinkedBlockingQueue?

答:

  • 数据量稳定,需要高性能:ArrayBlockingQueue
  • 数据量不确定,需要高吞吐:LinkedBlockingQueue
  • 防止 OOM,使用 LinkedBlockingQueue 时务必指定容量

面试题 2:为什么 LinkedBlockingQueue 并发能力比 ArrayBlockingQueue 强?

答:

  • LinkedBlockingQueue 采用双锁机制(生产者和消费者各有一把锁),生产和消费可并行。
  • ArrayBlockingQueue 采用单锁机制,生产和消费不能并行,导致并发能力稍逊。

总结

今天,我们通过小米的面试经历,深入解析了 ArrayBlockingQueue 和 LinkedBlockingQueue。面试官爱问的点,我们都帮大家整理好了!

核心记住三点:

  • 固定容量 vs 可扩展性:ArrayBlockingQueue 容量固定,LinkedBlockingQueue 可以无界。
  • 单锁 vs 双锁:LinkedBlockingQueue 并发能力更强。
  • 适用场景不同:ArrayBlockingQueue 适合高性能场景,LinkedBlockingQueue 适合高吞吐量场景。

END

希望这篇文章能帮助你在面试时稳拿 offer!如果觉得有用,记得点个赞+在看哦!

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!