概述
ArrayBlockingQueue是采用数组实现的有界阻塞线程安全队列。如果向已满的队列继续塞入元素,将导致当前的线程阻塞。如果向空队列获取元素,那么将导致当前线程阻塞。
实现原理
1、属性
// 存放元素的数组
final Object[] items;
// 提取数组元素的下标
int takeIndex;
// 往数组中添加元素的下标
int putIndex;
// 队列中元素的数量
int count;
// 可重入锁
final ReentrantLock lock;
// 取元素的等待队列
private final Condition notEmpty;
// 添加元素的等待队列
private final Condition notFull;
2、构造器
public ArrayBlockingQueue(int var1) {
this(var1, false);
}
public ArrayBlockingQueue(int var1, boolean var2) {
this.itrs = null;
if (var1 <= 0) {
throw new IllegalArgumentException();
} else {
this.items = new Object[var1];
this.lock = new ReentrantLock(var2);
this.notEmpty = this.lock.newCondition();
this.notFull = this.lock.newCondition();
}
}
public ArrayBlockingQueue(int var1, boolean var2, Collection<? extends E> var3) {
this(var1, var2);
ReentrantLock var4 = this.lock;
var4.lock();
try {
int var5 = 0;
Object var7;
try {
for(Iterator var6 = var3.iterator(); var6.hasNext(); this.items[var5++] = var7) {
var7 = var6.next();
checkNotNull(var7);
}
} catch (ArrayIndexOutOfBoundsException var11) {
throw new IllegalArgumentException();
}
this.count = var5;
this.putIndex = var5 == var1 ? 0 : var5;
} finally {
var4.unlock();
}
}
创建ArrayBlockingQueue队列的时候,需要指定数组的大小,同时采用的是非公平锁的机制。
3、核心方法
public interface BlockingQueue<E> extends Queue<E> {
// 将给定元素设置到队列中,如果设置成功返回true, 否则返回false。
// 如果是往限定了长度的队列中设置值,推荐使用offer()方法。
boolean add(E var1);
// 将给定的元素设置到队列中,如果设置成功返回true, 否则返回false. e的值不能为空,
// 否则抛出空指针异常。
boolean offer(E var1);
// 将元素设置到队列中,如果队列中没有多余的空间,该方法会一直阻塞,
// 直到队列中有多余的空间。
void put(E var1) throws InterruptedException;
// 将给定元素在给定的时间内设置到队列中,如果设置成功返回true, 否则返回false.
boolean offer(E var1, long var2, TimeUnit var4) throws InterruptedException;
// 从队列中获取值,如果队列中没有值,线程会一直阻塞,
// 直到队列中有值,并且该方法取得了该值。
E take() throws InterruptedException;
// 在给定的时间里,从队列中获取值,时间到了直接调用普通的poll方法,
// 为null则直接返回null。
E poll(long var1, TimeUnit var3) throws InterruptedException;
// 获取队列中剩余的空间。
int remainingCapacity();
// 从队列中移除指定的值。
boolean remove(Object var1);
// 判断队列中是否拥有该值。
boolean contains(Object var1);
// 将队列中值,全部移除,并发设置到给定的集合中
int drainTo(Collection<? super E> var1);
// 指定最多数量限制将队列中值,全部移除,并发设置到给定的集合中。
int drainTo(Collection<? super E> var1, int var2);
}
ArrayBlockQueue与LinkedBlockQueue的对比
不同点
1、存储,获取数据方式不同
ArrayBlockQueue是基础数组进行存储的,而LinkedBlockQueue是基础Node节点进行链式存储的。
LinkedBlockQueue在高并发的时候,可以进行往队列中边存数据,边取数据。
2、生产,消费使用的锁是不一样的
ArrayBlockQueue生产,消费都是使用同一个锁;LinkedBlockQueue生产,消费是不同锁。
3、初始化的大小不同
ArrayBlockQueue必须指定初始化大小。而LinkedBlockQueue可以不默认指定,创建的是一个MAX.Interger_value大小的队列。
相同点
1、默认获取锁的方式是一样的,都是非公平锁