文章目录
-
- 1. 简介
- 2. 继承体系
- 3. 字段
- 4. 构造器
- 5. 常用方法
1. 简介
public class ArrayBlockingQueue<E> extends AbstractQueue<E>implements BlockingQueue<E>, java.io.Serializable {
}
ArrayBlockingQueue 是 JUC 包下一个以数组实现的有界阻塞队列,它是线程安全的。它不需要扩容,因为它是初始化时指定容量并利用 takeIndex 和 putIndex 两个属性来实现数组的循环利用。
ArrayBlockingQueue 的缺点:
- 队列长度固定且必须在初始化时指定,所以使用之前一定要慎重考虑好容量;
- 如果消费速度跟不上入队速度,则会导致提供者线程一直阻塞,且越阻塞越多,非常危险;
- 只使用了一个锁来控制入队出队,效率较低,那是不是可以借助分段的思想把入队出队分裂成两个锁呢?答案是 LinkedBlockingQueue
2. 继承体系
3. 字段
// 使用数组存储元素
final Object[] items;// 取元素的指针,利用这个指针循环利用数组取出元素
int takeIndex;// 放元素的指针,利用这个指针循环利用数组存储元素
int putIndex;// 元素数量
int count;// 利用重入锁来保证并发安全
final ReentrantLock lock;// 非空条件
private final Condition notEmpty;// 非满条件
private final Condition notFull;
4. 构造器
- ArrayBlockingQueue 初始化时必须传入容量,也就是数组的大小
public ArrayBlockingQueue(int capacity) { this(capacity, false); }
- 可以通过构造方法控制重入锁的类型是公平锁还是非公平锁
public ArrayBlockingQueue(int capacity, boolean fair) { if (capacity <= 0)throw new IllegalArgumentException();// 初始化数组this.items = new Object[capacity];// 创建重入锁及两个条件lock = new ReentrantLock(fair);notEmpty = lock.newCondition();notFull = lock.newCondition(); }
5. 常用方法
- public boolean add(E e):add(e)时如果队列满了则抛出异常
- public boolean offer(E e):offer(e)时如果队列满了则返回false
- public void put(E e) throws InterruptedException:put(e)时如果队列满了则使用notFull等待
- public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException:offer(e, timeout, unit)时如果队列满了则等待一段时间后如果队列依然满就返回false
- public E remove():remove()时如果队列为空则抛出异常
- public E poll():poll()时如果队列为空则返回null
- public E take() throws InterruptedException:take()时如果队列为空则阻塞等待在条件notEmpty上
- public E poll(long timeout, TimeUnit unit) throws InterruptedException:poll(timeout, unit)时如果队列为空则阻塞等待一段时间后如果还为空就返回null