写点什么

ArrayBlockingQueue 源码分析 - 新增和获取数据

作者:zarmnosaj
  • 2022 年 7 月 10 日
  • 本文字数:1157 字

    阅读完需:约 4 分钟

新增

public void put(E e) throws InterruptedException {    checkNotNull(e);    final ReentrantLock lock = this.lock;    lock.lockInterruptibly();    try {        while (count == items.length)            notFull.await();        enqueue(e);    } finally {        lock.unlock();    }}
private void enqueue(E x) { // assert lock.getHoldCount() == 1; // assert items[putIndex] == null; final Object[] items = this.items; items[putIndex] = x; if (++putIndex == items.length) putIndex = 0; count++; notEmpty.signal();}
复制代码


checkNotNull(e); 元素不能为空


while (count == items.length) notFull.await();队列如果是满的,就无限等待, 一直等待队列中有数据被拿走时,自己被唤醒


items[putIndex] = x; putIndex 为本次插入的位置


if (++putIndex == items.length) putIndex = 0; ++ putIndex 计算下次插入的位置,如果下次插入的位置,正好等于队尾,下次插入就从 0 开始


notEmpty.signal();唤醒因为队列空导致的等待线程


数据新增都会按照 putIndex 的位置进行新增,如果队列满,无限阻塞。主要新增分为了两种情况:


  1. 如果新增的位置居中,则直接新增.

  2. 如果新增的位置到队尾了,则下次新增时就要从头开始

获取数据

public E take() throws InterruptedException {    final ReentrantLock lock = this.lock;    lock.lockInterruptibly();    try {        while (count == 0)            notEmpty.await();        return dequeue();    } finally {        lock.unlock();    }}
private E dequeue() { final Object[] items = this.items; E x = (E) items[takeIndex]; items[takeIndex] = null; if (++takeIndex == items.length) takeIndex = 0; count--; if (itrs != null) itrs.elementDequeued(); notFull.signal(); return x;}
复制代码


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 开始了。

发布于: 刚刚阅读数: 4
用户头像

zarmnosaj

关注

靡不有初,鲜克有终 2020.02.06 加入

成都后端混子

评论

发布
暂无评论
ArrayBlockingQueue源码分析-新增和获取数据_7月月更_zarmnosaj_InfoQ写作社区