目录
1.概述
- ArrayBlockingQueue 是 BlockingQueue 接口的有界阻塞队列实现类,底层采用数组来实现。
特点
- ArrayBlockingQueue一旦创建,容量不能改变。
- 其并发控制采用可重入锁来控制,不管是插入操作还是读取操作,都需要获取到锁才能进行操作。
- ArrayBlockingQueue 默认情况下不能保证线程访问队列的公平性,
- 所谓公平性是指严格按照线程等待的绝对时间顺序,即最先等待的线程能够最先访问到 ArrayBlockingQueue。
- 而非公平性则是指访问 ArrayBlockingQueue 的顺序不是遵守严格的时间顺序,有可能存在,
当 ArrayBlockingQueue 可以被访问时,长时间阻塞的线程依然无法访问到 ArrayBlockingQueue。如果保证公平性,通常会降低吞吐量。如果需要获得公平性的 ArrayBlockingQueue,可采用如下代码:
private static ArrayBlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(10,true);
2.使用案例
使用案例见上一篇博客:https://blog.csdn.net/qq_34805255/article/details/101924873
3.源码分析
3.1 重要属性
public class ArrayBlockingQueue {
/**
* ArrayBlockingQueue的底层实现为此数组
*
* 并且可以看到此数组被final修饰,数组一旦创建,容量不可变(数组本身的性质),并且,数组引用指向的数组对象不可变
*/
final Object[] items;
/**
* 队首索引位置
*/
int takeIndex;
/**
* 队尾索引位置
*/
int putIndex;
/**
* 队列中元素的个数
*/
int count;
/**
* 采用ReentrantLock来保证线程安全
*/
final ReentrantLock lock;
/**
* 为了保证消费(take)数据的时候如果为空的时候,进行阻塞(等待),使用了Condition
*
* 当获取数据的消费者线程被阻塞时会将该线程放置到notEmpty等待队列中(notEmpty可以理解为等待队列不空的等待队列)
*/
private final Condition notEmpty;
/**
* 为了保证生产(put)数据的时候如果队列满的时候,进行阻塞(等待),使用了Condition
*
* 当插入数据的生产者线程被阻塞时,会将该线程放置到notFull等待队列中(notFull可以理解为等待队列不满的等待队列)。
*/
private final Condition notFull;
}
- 底层采用final数组items实现
- 使用锁ReentrantLock保证线程安全
- 使用两个Condition来实现阻塞
3.2 构造方法
/**
* 我们在创建一个ArrayBlockingQueue时,必须传入容量用做创建数组的大小
*
* 当我们不传入是否使用公平锁时,默认是非公平的
*/
public ArrayBlo