奇安信一面:咱们聊一聊什么叫做阻塞队列的有界和无界?

createh520小时前技术教程1

面试官:什么叫做阻塞队列的有界和无界?能否结合源码分析一下?并站在架构设计的角度谈谈它们的作用。

我:好的,这个问题很有意思,我来为您详细解释一下。


1. 阻塞队列的有界和无界

(1) 有界阻塞队列

  • 定义:有界阻塞队列有一个固定的容量上限。例如,你可以定义一个容量为10的队列,一旦队列满了,再往队列中添加元素就会被阻塞,直到队列中有空闲空间。
  • 源码示例:在Java中,ArrayBlockingQueue是一个典型的有界阻塞队列。它的构造函数中需要指定容量大小,当队列满时,put方法会阻塞,直到有空间可用。
  • 架构设计的作用
  • 防止资源耗尽:有界队列可以限制队列的最大容量,从而防止系统资源被无限制地占用。
  • 控制生产者速度:当队列满了,生产者线程会被阻塞,这可以间接控制生产者的速度,避免生产者过快地生成任务。

(2) 无界阻塞队列

  • 定义:无界阻塞队列的容量理论上是无限的,生产者可以不断地往队列中添加元素,而不用担心队列满。
  • 源码示例:LinkedBlockingQueue在不指定容量时,默认是无界的(实际上是受限于内存大小)。生产者线程不会因为队列满而被阻塞。
  • 架构设计的作用
  • 简单易用:生产者不需要关心队列是否满了,只需不断地添加任务即可。
  • 性能问题:无界队列可能会导致系统资源被无限制地占用,比如内存溢出。

2. 架构设计中的选择

(1) 有界队列的优势

  • 资源控制:有界队列可以有效防止系统资源被过度占用,避免内存泄漏。
  • 系统稳定性:通过限制队列大小,可以避免生产者过快地生成任务,从而保证系统的稳定性和可靠性。

(2) 无界队列的劣势

  • 资源耗尽风险:无界队列可能会导致系统资源被无限制地占用,甚至引发内存溢出。
  • 缺乏控制:生产者可能会过度生成任务,导致系统负载过高。

3. 结合源码分析

(1) ArrayBlockingQueue(有界)

java复制

public ArrayBlockingQueue(int capacity, boolean fair) {
    if (capacity <= 0)
        throw new IllegalArgumentException();
    this.items = new Object[capacity]; // 定义固定大小的数组
    this.capacity = capacity;
    this.lock = new ReentrantLock(fair);
    this.notEmpty = lock.newCondition();
    this.notFull = lock.newCondition();
}
  • 核心逻辑:当队列满时,put方法会阻塞,直到有空间可用。
  • 架构设计:有界队列通过限制容量,避免了资源耗尽的问题。

(2) LinkedBlockingQueue(无界)

java复制

public LinkedBlockingQueue() {
    this(Integer.MAX_VALUE); // 默认容量为Integer.MAX_VALUE,接近无界
}
  • 核心逻辑:生产者线程不会因为队列满而被阻塞。
  • 架构设计:无界队列简化了设计,但需要小心资源耗尽的问题。

4. 架构设计建议

在实际架构设计中,建议优先使用有界阻塞队列,因为它可以有效防止资源耗尽和生产者过快生成任务,从而保证系统的稳定性和可靠性。当然,具体选择还需要根据业务需求和资源情况进行权衡。


面试官:好的,谢谢你的回答!

相关文章

一篇文章搞懂同步与异步、阻塞与非阻塞

要想掌握好Java NIO需要涉及了解同步与异步、阻塞与非阻塞,本文通过相关例子让你深入理解其本质@mikechen阻塞阻塞与非阻塞是对同一个线程来说的,在某个时刻,线程要么处于阻塞,要么处于非阻塞。...

数组阻塞队列ArrayBlockingQueue底层数据结构和使用场景

1. 数组存储元素:ArrayBlockingQueue 使用一个固定大小的数组来存储队列中的元素。在创建 ArrayBlockingQueue 实例时,需要指定数组的容量,例如:BlockingQu...

终于有人把Java程序员都要学的知识点整理了,令人茅塞顿开

JVM无论处于何种层级的 Java 从业者,JVM 皆为其在进阶之途上必然需要跨越的一道难关。不论是在日常的工作情境之中,还是在至关重要的面试环节里,JVM 均是不可或缺的必考之题。倘若对 JVM 缺...

阻塞模型将会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?

使用 Java 阻塞 I/O 模型读取数据,将会导致线程阻塞,线程将会进入休眠,从而让出 CPU 的执行权,直到数据读取完成。这个期间如果使用 jstack 查看线程状态,却可以发现Java 线程状态...

JAVA并发之BlockingQueue(阻塞队列)

Java从JDK5开始在并发包内引入了BlockingQueue(阻塞队列),它除了提供队列的FIFO功能之外,还提供了额外的功能,例如:当获取队列内容时发现队列为空,则等待其变为非空。当往队列存储内...

技术干货分享:RabbitMQ消息积压的几种解决思路

在日常工作中使用RabbitMQ偶尔会遇不可预料的情况导致的消息积压,一般出现消息积压基本上分为几种情况:消费者消费消息的速度赶不上生产速度,这种问题主要是业务逻辑没设计好消费者和生产者之间的平衡,需...