ArrayBlockingQueue源码解析
核心点
ArrayBlockingQueue的继承关系:1
2public class ArrayBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable
继承Queue,实现了BlockingQueue的方法。
这款queue的核心是一个object数组。1
2/** The queued items */
final Object[] items;
第二个核心是一个cas实现的锁。1
2
3
4
5
6
7
8/** Main lock guarding all access */
final ReentrantLock lock;
/** Condition for waiting takes */
private final Condition notEmpty;
/** Condition for waiting puts */
private final Condition notFull;
就下图这些东西。
源码分析
这里分析下入对和出队1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36public void put(E e) throws InterruptedException {
//这里是校验
Objects.requireNonNull(e);
//获取锁
final ReentrantLock lock = this.lock;
//加锁
lock.lockInterruptibly();
try {
//如果这个时候队列满的,那么就无限循环,等待被唤醒。这个时候出让cpu资源
while (count == items.length)
notFull.await();
//退出循环了,这个时候开始入队列操作
enqueue(e);
} finally {
lock.unlock();
}
}
/**
* Inserts element at current put position, advances, and signals.
* Call only when holding lock.
*/
private void enqueue(E e) {
// assert lock.isHeldByCurrentThread();
// assert lock.getHoldCount() == 1;
// assert items[putIndex] == null;
//指针引用
final Object[] items = this.items;
//添加元素
items[putIndex] = e;
//判断是否满,满的话,下标指到第一个元素。
if (++putIndex == items.length) putIndex = 0;
count++;
//唤醒notEmpty.await(),这个await应该是get的时候去判断是否空,如果空的话,就等元素入队列
notEmpty.signal();
}
出队列差不多。是个相反的过程。哦,对了,出队列,原来的下标对应的置空,便于gc回收。
本文作者 : braveheart
原文链接 : https://zhangjun075.github.io/passages/ArrayBlockingQueue源码解析/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
知识 & 情怀 | 二者兼得