类图结构
同样,为了能从全局一览ArrayBlockingQueue的内部构造,先来看它的类图。
ArrayBlockingQueue的内部有一个数组items,用来存放队列元素,putindex变量表示入队元素下标,takelndex是出队下标,count统计队列元素个数。
从定义可知,这些变量并没有使用volatile修饰,这是因为访问这些变量都是在锁块内,而加锁已经保证了锁块内变量的内存可见性了。
另外有个独占锁lock用来保证出、入队操作的原子性,这保证了同时只有一个线程可以进行入队、出队操作。
另外,notEmpty、notFull条件变量用来进行出、入队的同步。
另外,由于ArrayBlockingQueue是有界队列,所以构造函数必须传入队列大小参数。构造函数的代码如下。
ArrayBlockingQueue 原理介绍
offer 操作
向队列尾部插入一个元素,如果队列有空闲空间则插入成功后返回 true,如果队列已满则丢弃当前元素然后返回false。
如果e元素为null则抛出NullPointerException异常。另外,该方法是不阻塞的。
put操作
向队列尾部插入一个元素,如果队列有空闲则插入后直接返回true,如果队列已满则阻塞当前线程直到队列有空闲并插入成功后返回true,如果在阻塞时被其他线程设置了中断标志,则被阻塞线程会抛出InteruptedException异常而返回。
另外,如果e元素为null则抛出NullPointerException异常。
poll操作
从队列头部获取并移除一个元素,如果队列为空则返回null,该方法是不阻塞的。
take操作
获取当前队列头部元素并从队列里面移除它。
如果队列为空则阻塞当前线程直到队列不为空然后返回元素,如果在阻塞时被其他线程设置了中断标志,则被阻塞线程会抛出InterruptedException异常而返回。
peek操作
获取队列头部元素但是不从队列里面移除它,如果队列为空则返回null,该方法是不阻塞的。
size操作
计算当前队列元素个数。