MST

星途 面试题库

面试题:Java中ArrayBlockingQueue容量限制的基本应用

请说明在Java中,ArrayBlockingQueue是如何实现容量限制的?如果向已满的ArrayBlockingQueue中添加元素,会发生什么情况?请通过代码示例展示这两种情况。
30.2万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. ArrayBlockingQueue实现容量限制的原理
    • ArrayBlockingQueue内部使用一个数组来存储元素,在创建ArrayBlockingQueue实例时,需要指定一个容量参数capacity。这个capacity决定了数组的大小,也就是队列能容纳的最大元素数量。
    • 队列通过维护两个指针(takeIndexputIndex)来管理元素的插入和取出位置,当putIndex到达数组末尾时,会循环回到数组开头,以实现循环利用数组空间。同时,通过一个计数器count来记录当前队列中的元素数量,当count等于capacity时,队列就达到了容量限制。
  2. 向已满的ArrayBlockingQueue中添加元素的情况
    • add(E e)方法:如果队列已满,调用add方法会抛出IllegalStateException异常。
    • offer(E e)方法:如果队列已满,调用offer方法会返回false,表示添加元素失败,不会抛出异常。
    • put(E e)方法:如果队列已满,调用put方法会使当前线程阻塞,直到队列有空间可以插入新元素。
  3. 代码示例
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class ArrayBlockingQueueExample {
    public static void main(String[] args) {
        // 创建一个容量为3的ArrayBlockingQueue
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(3);

        // 使用add方法向已满队列添加元素
        queue.add(1);
        queue.add(2);
        queue.add(3);
        try {
            queue.add(4); // 这会抛出IllegalStateException异常
        } catch (IllegalStateException e) {
            System.out.println("add方法:队列已满,抛出异常: " + e.getMessage());
        }

        // 使用offer方法向已满队列添加元素
        boolean offerResult = queue.offer(4);
        System.out.println("offer方法:添加结果为 " + offerResult);

        // 使用put方法向已满队列添加元素
        new Thread(() -> {
            try {
                System.out.println("put方法:尝试添加元素4");
                queue.put(4);
                System.out.println("put方法:元素4已添加到队列");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        // 主线程睡眠2秒,以便观察put方法的阻塞效果
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("主线程:从队列中取出一个元素,为队列腾出空间");
        try {
            queue.take();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

上述代码中展示了addofferput方法在向已满ArrayBlockingQueue添加元素时的不同行为。add方法在队列满时抛出异常,offer方法返回falseput方法会阻塞当前线程直到队列有空间。