美文网首页
CopyOnWriteArrayList

CopyOnWriteArrayList

作者: Jokerone_ | 来源:发表于2017-03-26 22:13 被阅读0次
    1.png

    特点

    任何可变的操作(add,set,remove)都会伴随着复制操作。
    允许为空。允许重复数据。有序的。线程安全的。

    问题

    CopyOnWriteArrayList是否会发生ConcurrentModificationException?
    <small>答:不会。因为CopyOnWriteArrayList任何可变的操作都会伴随着复制操作,所以,迭代器iterator()只是拿到了一个快照。因此,它的迭代器也是弱一致性的。</small>

    基本属性

        /** The lock protecting all mutators */
        transient final ReentrantLock lock = new ReentrantLock();
    
        /** The array, accessed only via getArray/setArray. */
        private volatile transient Object[] array;
    

    构造器

        /**
         * Creates an empty list.
         */
        public CopyOnWriteArrayList() {
            setArray(new Object[0]);
        }
    

    add()

        /**
         * Appends the specified element to the end of this list.
         *
         * @param e element to be appended to this list
         * @return <tt>true</tt> (as specified by {@link Collection#add})
         */
        public boolean add(E e) {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                Object[] elements = getArray();
                int len = elements.length;
                Object[] newElements = Arrays.copyOf(elements, len + 1);
                newElements[len] = e;
                setArray(newElements);
                return true;
            } finally {
                lock.unlock();
            }
        }
    

    get()

        // Positional Access Operations
    
        @SuppressWarnings("unchecked")
        private E get(Object[] a, int index) {
            return (E) a[index];
        }
    
        /**
         * {@inheritDoc}
         *
         * @throws IndexOutOfBoundsException {@inheritDoc}
         */
        public E get(int index) {
            return get(getArray(), index);
        }
    

    remove()

        /**
         * Removes the element at the specified position in this list.
         * Shifts any subsequent elements to the left (subtracts one from their
         * indices).  Returns the element that was removed from the list.
         *
         * @throws IndexOutOfBoundsException {@inheritDoc}
         */
        public E remove(int index) {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                Object[] elements = getArray();
                int len = elements.length;
                E oldValue = get(elements, index);
                int numMoved = len - index - 1;
                if (numMoved == 0)
                    //如果删除的是最后一个元素,直接copy就好了。
                    setArray(Arrays.copyOf(elements, len - 1));
                else {
                    Object[] newElements = new Object[len - 1];
                    //先copy index前面那部分。
                    System.arraycopy(elements, 0, newElements, 0, index);
                    //再copy index后面那部分。
                    System.arraycopy(elements, index + 1, newElements, index,
                                     numMoved);
                    setArray(newElements);
                }
                return oldValue;
            } finally {
                lock.unlock();
            }
        }
    

    相关文章

      网友评论

          本文标题:CopyOnWriteArrayList

          本文链接:https://www.haomeiwen.com/subject/rpzkottx.html