BlockingQueue的实现类ArrayBlockingQueue,见名思意,是基于数组实现的BlockingQueue。在《BlockingQueue初识》中,对BlockingQueue进行了介绍,BlockingQueue定义和约束了相关方法的行为。学习ArrayBlockingQueue,就是观察其是如何借助数组去实现BlockingQueue中定义和约束的方法的。
ArrayBlockingQueue借助了ReentrantLock与condition来保证线程安全以及实现阻塞等待的功能,关于ReentrantLock的介绍请戳《JUC之ReentrantLock》
█ 字段
在ArrayBlockingQueue中定义了如何几个字段。
final Object[] items;
int takeIndex;
int putIndex;
int count;
final ReentrantLock lock;
private final Condition notEmpty;
private final Condition notFull;
transient Itrs itrs = null;
- items
数组items,用于存在BlockingQueue中的元素。ArrayBlockingQueue借助于数组,就是借助items数组来存放元素。往ArrayBlockingQueue中添加和移出元素就是向items数组中存放和取出元素数据。items数组的大小在初始化的时候便确定了长度,无法扩容和缩容改变,即items数组是一个定长数组。
- takeIndex
一个items数组下标,用于标记下一次该被取出(take, poll, peek 或 remove)的元素的位置。
- putIndex
一个items数组下标,用于标记下一次添加(put, offer 或 add)的元素该存放的位置。
- count
ArrayBlockingQueue中元素的个数。(注意这个count是items数组的长度,count的大小小于或等于items数组的长度)当count等于0时,表示items数组中还没有任何元素,当count等于items数组的长度则表示数组已满。
- lock、notEmpty、notFull
BlockingQueue的具有阻塞等待的Queue,ArrayBlockingQueue实现阻塞等待的功能借助了ReentrantLock与Condition实现线程间的通信。
- itrs
迭代器,用于遍历ArrayBlockingQueue。
补充:
关于定义takeIndex与putIndex来标记数组中取元素和添加元素的位置,是因为将items数组看成一个环形。关于往往定长数组中存放和取出元素,有两种实现方式。
(1)取出元素始终取0号下标的元素,此时只需要标记下次元素可以存放的位置putIndex即可。