写点什么

ArrayBlockingQueue 源码分析 - 删除数据

作者:zarmnosaj
  • 2022 年 7 月 11 日
  • 本文字数:1056 字

    阅读完需:约 3 分钟

删除数据

源码:


void removeAt(final int removeIndex) {    final Object[] items = this.items;    if (removeIndex == takeIndex) {        items[takeIndex] = null;        if (++takeIndex == items.length)            takeIndex = 0;        count--;        if (itrs != null)            itrs.elementDequeued();    } else {        final int putIndex = this.putIndex;        for (int i = removeIndex;;) {            int next = i + 1;            if (next == items.length)                next = 0;            if (next != putIndex) {                items[i] = items[next];                i = next;            } else {                items[i] = null;                this.putIndex = i;                break;            }        }        count--;        if (itrs != null)            itrs.removedAt(removeIndex);    }    notFull.signal();}
复制代码


if (removeIndex == takeIndex) { items[takeIndex] = null; if (++takeIndex == items.length) takeIndex = 0; count--; if (itrs != null) itrs.elementDequeued();删除情况 1:如果删除位置正好等于下次要拿数据的位置,则把下次要拿数据的位置置为空,然后把要拿数据的位置往后移动一位,将当前数组的大小减一。


final int putIndex = this.putIndex; ... int next = i + 1; if (next == items.length) next = 0; if (next != putIndex) { items[i] = items[next]; i = next; } else { items[i] = null; this.putIndex = i; break; ... }删除情况 2:找到要删除元素的下一个,如果下一个元素不等于 putIndex,则将下一个元素往前移动一位,如果下一个元素等于 putIndex,则直接删除元素,下次放元素时会从本次删除的元素位置放。


总结一下,删除元素主要分为两种情况:1:删除位置和 takeIndex 的关系:删除位置和 takeIndex 一样,比如 takeIndex 是 3, 而要删除的位置正好也是 3,那么就把位置 3 的数据置为 null ,并重新计算 takeIndex 为 4。2:找到要删除元素的下一个,计算删除元素和 putIndex 的关系如果下一个元素不是 putIndex,就把下一个元素往前移动一位如果下一个元素是 putIndex,把 putIndex 的值修改成删除的位置

总结

ArrayBlockingQueue 底层的数据结构是有界的数组,大体上和其它队列差别不多,只是 ArrayBlockingQueue 当 takeIndex、putIndex 到队尾的时候,都会重新从 0 开始循环,相当于是一个环,这是需要注意的点。

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

zarmnosaj

关注

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

成都后端混子

评论

发布
暂无评论
ArrayBlockingQueue源码分析-删除数据_7月月更_zarmnosaj_InfoQ写作社区