Java集合-ArrayBlockingQueue
特性
public class ArrayBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
BlockingQueue:定义了队列的入队出队的方法
AbstractQueue:入队出队的基本操作
成员变量
组成:一个对象数组+1把锁ReentrantLock+2个条件Condition
// 使用数组存储元素
final Object[] items;
// 取元素的指针 记录下一次操作的位置
int takeIndex;
// 放元素的指针 记录下一次操作的位置
int putIndex;
// 元素数量
int count;
// 保证并发访问的锁
final ReentrantLock lock;
// 等待出队的条件 消费者监视器
private final Condition notEmpty;
// 等待入队的条件 生产者监视器
private final Condition notFull;
构造器
//必须传入容量,可以控制重入锁是公平还是非公平
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();
}
public ArrayBlockingQueue(int capacity, boolean fair, Collection<? extends E> c) {
this(capacity, fair);
// final修饰的变量不会发生指令重排
final ReentrantLock lock = this.lock;
// 保证可见性 不是为了互斥 防止指令重排 保证item的安全
lock.lock();
try {
int i = 0;
try {
for (E e : c) {
checkNotNull(e);
items[i++] = e;
}
} catch (ArrayIndexOutOfBoundsException ex) {
throw new IllegalArgumentException();
}
count = i;
putIndex = (i == capacity) ? 0 : i;
} finally {
lock.unlock();
}
}
对象创建三步:2和3可能会发生重排(互相不依赖)
1、分配内存空间;
2、初始化对象;
3、将内存空间的地址赋值给对应的引用。