java并发编程之 CopyOnWriteArrayList

来源:互联网 发布:网络关注平台出租 编辑:程序博客网 时间:2024/06/14 03:53

我们都知道在java容器中ArrayList是线程不安全的,而vector是线程安全的。那么针对线程安全和不安全来说,这两个容器应该是够用了,为什么还要出现一个CopyOnWriteArrayList这个容器呢?CopyOnWriteArrayList是线程安全的,那么它较vector有哪些优势呢?

看一下vector的add和get源码

/**     * Appends the specified element to the end of this Vector.     *     * @param e element to be appended to this Vector     * @return {@code true} (as specified by {@link Collection#add})     * @since 1.2     */    public synchronized boolean add(E e) {        modCount++;        ensureCapacityHelper(elementCount + 1);        elementData[elementCount++] = e;        return true;    }/**     * Returns the element at the specified position in this Vector.     *     * @param index index of the element to return     * @return object at the specified index     * @throws ArrayIndexOutOfBoundsException if the index is out of range     *            ({@code index < 0 || index >= size()})     * @since 1.2     */    public synchronized E get(int index) {        if (index >= elementCount)            throw new ArrayIndexOutOfBoundsException(index);        return elementData(index);    }

可以看到对于vector的add和get方法都被synchronize修饰了,这就说明了当我在获取数据的时候,其他线程也是不能获取的,所有的读和写都会被阻塞。

再来看CopyOnWriteArrayList中的源码

/**     * Inserts the specified element at the specified position in this     * list. Shifts the element currently at that position (if any) and     * any subsequent elements to the right (adds one to their indices).     *     * @throws IndexOutOfBoundsException {@inheritDoc}     */    public void add(int index, E element) {        final ReentrantLock lock = this.lock;        lock.lock();        try {            Object[] elements = getArray();            int len = elements.length;            if (index > len || index < 0)                throw new IndexOutOfBoundsException("Index: "+index+                                                    ", Size: "+len);            Object[] newElements;            int numMoved = len - index;            if (numMoved == 0)                newElements = Arrays.copyOf(elements, len + 1);            else {                newElements = new Object[len + 1];                System.arraycopy(elements, 0, newElements, 0, index);                System.arraycopy(elements, index, newElements, index + 1,                                 numMoved);            }            newElements[index] = element;            setArray(newElements);        } finally {            lock.unlock();        }    }

简单的概括就是,在添加数据的时候,系统会复制一个新的list然后添加的时候往新的array添加,当然这个新的list是lock确保线程安全的。

等新的list操作完成之后,再把旧的list引用的地址指向它即可。但是旧的list是没有加锁的,所以读的操作是不会阻塞的。

copyOnWriterArrayList通过消耗空间的方式来提高系统的并发性,但是这样浪费了空间,容易造成minor Gc ,严重的话会造成full gc。所以要根据情况来选择使用。

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 茄汁豆腐干 干豆腐干 但氏豆腐干 干豆腐炒 豇豆干 豇豆干怎么做 干豇豆红烧肉 凉拌莴笋干 干豇豆炖腊排骨 西兰花干 豇豆干炒肉 辣炒干豆角 干豆角炒肉 炒干豆角 干炒豆角 豆角干的做法 豆角干怎么做好吃 红烧肉烧干豆角的做法 干豆角丝 干豆角批发价格 干豆角的吃做法大全集 红烧肉炖干豆角的做法 干豆角的做法大全家常 干豆角丝的做法 红烧肉干豆角的做法 炒干豆角的家常做法 干豆角烧肉的家常做法 红烧肉炖干豆角 干豆角炒肉的家常做法 干炸豆角的做法 干豆角收购商 干豆角炒腊肉 干煸长豆角 干豆角怎么做 素干煸豆角的家常做法 干煸豆角的家常做法 干豆角烧肉的做法 素炒干豆角怎么做好吃 干煸长豆角的家常做法 干炒豆角的做法 干煸豆角的做法图解