您当前的位置: 首页 >  ar

顧棟

暂无认证

  • 1浏览

    0关注

    227博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【JUC系列】并发容器之CopyOnWrite(CopyOnWriteArrayList、CopyOnWriteArraySet)

顧棟 发布时间:2022-05-07 18:09:52 ,浏览量:1

CopyOnWrite

文章目录
  • CopyOnWrite
    • CopyOnWriteArrayList
      • 核心组成
        • 内部类-迭代器COWIterator
        • 成员变量
        • 构造函数
        • 核心方法
          • **boolean add(E e)**
          • **addIfAbsent(E e, Object[] snapshot)**
          • **remove(int index)**
          • **set(int index, E element)**
        • Arrays.copyOf方法
        • System.arraycopy方法
      • 示例
      • 使用场景
    • CopyOnWriteArraySet

CopyOnWriteArrayList

java.util.ArrayList 的线程是安全的,其中所有可变操作(添加、设置等)都是通过制作底层数组的新副本来实现的。

这通常成本太高,但当遍历操作的数量大大超过突变时,它可能比替代方法更有效,并且在您不能或不想同步遍历但需要排除并发线程之间的干扰时很有用。

snapshot风格的迭代器方法使用对创建迭代器时数组状态的引用。这个数组在迭代器的生命周期内永远不会改变,所以干扰是不可能的,并且迭代器保证不会抛出ConcurrentModificationException。自创建迭代器以来,迭代器不会反映对列表的添加、删除或更改。不支持迭代器本身的元素更改操作(删除、设置和添加)。这些方法抛出UnsupportedOperationException

允许所有元素,包括 null。

此类实现了List, RandomAccess, Cloneable, java.io.Serializable四个类说明。

  • 支持对列表的基本操作
  • 支持随机访问
  • 支持克隆
  • 支持可序列化
核心组成 内部类-迭代器COWIterator
    static final class COWIterator implements ListIterator {
        /** 作为快照的数组 */
        private final Object[] snapshot;
        /** 数组的下标 可以理解为游标 */
        private int cursor;

        /** 构造函数 传入参数为元素数组和数组游标*/
        private COWIterator(Object[] elements, int initialCursor) {
            cursor = initialCursor;
            snapshot = elements;
        }

        /** 通过比较游标与快照数组的长度比较,检查快照数组是否还有元素*/
        public boolean hasNext() {
            return cursor  0;
        }

        /** 获取下一个元素项*/
        @SuppressWarnings("unchecked")
        public E next() {
            if (! hasNext())
                throw new NoSuchElementException();
            return (E) snapshot[cursor++];
        }

        /** 获取前一个元素项*/
        @SuppressWarnings("unchecked")
        public E previous() {
            if (! hasPrevious())
                throw new NoSuchElementException();
            return (E) snapshot[--cursor];
        }

        /** 下个游标值*/
        public int nextIndex() {
            return cursor;
        }

        /** 前一个游标值*/
        public int previousIndex() {
            return cursor-1;
        }

        /**
         * Not supported. Always throws UnsupportedOperationException.
         * @throws UnsupportedOperationException always; {@code remove}
         *         is not supported by this iterator.
         * 不支持remove
         */
        public void remove() {
            throw new UnsupportedOperationException();
        }

        /**
         * Not supported. Always throws UnsupportedOperationException.
         * @throws UnsupportedOperationException always; {@code set}
         *         is not supported by this iterator.
         * 不支持set
         */
        public void set(E e) {
            throw new UnsupportedOperationException();
        }

        /**
         * Not supported. Always throws UnsupportedOperationException.
         * @throws UnsupportedOperationException always; {@code add}
         *         is not supported by this iterator.
         * 不支持add
         */
        public void add(E e) {
            throw new UnsupportedOperationException();
        }

        /** 遍历数组支持Consumer*/
        @Override
        public void forEachRemaining(Consumer action) {
            Objects.requireNonNull(action);
            Object[] elements = snapshot;
            final int size = elements.length;
            for (int i = cursor; i = index && (e==null ? get(i)==null : e.equals(get(i)))),如果不存在则返回 -1 指数。int lastIndexOf(Object o)返回此列表中指定元素最后一次出现的索引,如果此列表不包含该元素,则返回 -1。 更正式地说,返回满足(o==null ? get(i)==null : o.equals(get(i))) 的最高索引 i,如果没有这样的索引,则返回 -1。int lastIndexOf(E e, int index)返回此列表中指定元素的最后一次出现的索引,从索引向后搜索,如果未找到该元素,则返回 -1。 更正式地说,返回最高索引 i 使得(i  c)从此列表中删除包含在指定集合中的所有元素。 由于需要内部临时数组,因此在此类中这是一项特别昂贵的操作。boolean retainAll(Collection c)仅保留此列表中包含在指定集合中的元素。 换句话说,从这个列表中删除所有不包含在指定集合中的元素。int addAllAbsent(Collection            
关注
打赏
1663402667
查看更多评论
0.0498s