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