ArrayBlockingQueue 源码分析 - 新增和获取数据
新增
checkNotNull(e);
元素不能为空
while (count == items.length) notFull.await();
队列如果是满的,就无限等待, 一直等待队列中有数据被拿走时,自己被唤醒
items[putIndex] = x;
putIndex 为本次插入的位置
if (++putIndex == items.length) putIndex = 0;
++ putIndex 计算下次插入的位置,如果下次插入的位置,正好等于队尾,下次插入就从 0 开始
notEmpty.signal();
唤醒因为队列空导致的等待线程
数据新增都会按照 putIndex 的位置进行新增,如果队列满,无限阻塞。主要新增分为了两种情况:
如果新增的位置居中,则直接新增.
如果新增的位置到队尾了,则下次新增时就要从头开始
获取数据
while (count == 0) notEmpty.await();
如果队列为空,无限等待,直到队列中有数据被 put 后,自己被唤醒
return dequeue();
从队列中拿数据
E x = (E) items[takeIndex];
takeIndex 代表本次拿数据的位置,是上一次拿数据时计算好的
items[takeIndex] = null;
帮助 gc
if (++takeIndex == items.length) takeIndex = 0;
++ takeIndex 计算下次拿数据的位置,如果正好等于队尾的话,下次就从 0 开始拿数据
count--;
队列实际大小减 1
notFull.signal();
唤醒被队列满所阻塞的线程
每次获取数据的位置就是 takeIndex 的位置,在找到本次应该获取的数据之后,会把 takeIndex 加 1,计算下次拿数据时的索引位置,有个特别的情况是:如果本次拿数据的位置已经是队尾了,那么下次拿数据的位置就要从头开始,就是从 0 开始了。
版权声明: 本文为 InfoQ 作者【zarmnosaj】的原创文章。
原文链接:【http://xie.infoq.cn/article/d30d960d791be2d753a42d126】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论