CopyOnWriteArraylist解析

    自从JDK1.5引入引入concurrentHashmap,CopyOnWriteArraylist等并发集合后,java集合体系获得了很大的完善,咱们有多了很多特殊情境的选择。     java

    咱们都知道,ArrayList存数数据的结构为数组,获取数据是根据数组下标,所以获取数据速度很快,而插入(中间)数据,删除数据却须要copy数组,所以速度较慢,而相比之下, CopyOnWriteArraylist底层的存储依然是数组,可是基本操做却不大同样。
数组


好处(使用场景):并发

 Copy-On-Write简称COW,是一种用于程序设计中的优化策略。其基本思路是,从一开始你们都在共享同一个内容,当某我的想要修改这个内容的时候,才会真正把内容Copy出去造成一个新的内容而后再改,这是一种延时懒惰策略。从JDK1.5开始Java并发包里提供了两个使用CopyOnWrite机制实现的并发容器,它们是CopyOnWriteArrayList和CopyOnWriteArraySet。CopyOnWrite容器很是有用,能够在很是多的并发场景中使用到。
app

CopyOnWriteArrayList经过修改时拷贝原数组,而获取数组时返回老数组(至关于快照),使得修改和查看(遍历)的线程操做的是不一样数组,达到避免并发修改的问题 性能

 

缺点(不宜使用):优化

     1.内存占用问题

     由于CopyOnWrite的写时复制机制,因此在进行写操做的时候,内存里会同时驻扎两个对象的内存,旧的对象和新写入的对象(注意:在复制的时候只是复制容器里的引用,只是在写的时候会建立新对象添加到新容器里,而旧容器的对象还在使用,因此有两份对象内存)。若是这些对象占用的内存比较大,好比说200M左右,那么再写入100M数据进去,内存就会占用300M,那么这个时候颇有可能形成频繁的Yong GC和Full GC。以前咱们系统中使用了一个服务因为每晚使用CopyOnWrite机制更新大对象,形成了每晚15秒的Full GC,应用响应时间也随之变长。 this

  针对内存占用问题,能够经过压缩容器中的元素的方法来减小大对象的内存消耗,好比,若是元素全是10进制的数字,能够考虑把它压缩成36进制或64进制。或者不使用CopyOnWrite容器,而使用其余的并发容器,如ConcurrentHashMapspa

 2.数据一致性问题

CopyOnWrite容器只能保证数据的最终一致性,不能保证数据的实时一致性。因此若是你但愿写入的的数据,立刻能读到,请不要使用CopyOnWrite容器。线程

        3.性能。

    每次写都要复制的操做天然形成操做性能的降低。设计

代码:

 添加

 

/**
     * 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();
        }
    }

 

经过Arrays的copyOf方式复制数组,同时,写的操做是须要并发控制的,采用了显示锁

写的操做直接对新的数组执行


 

获取数组

  final Object[] getArray() {
        return array;
    }

 


 

相关文章
相关标签/搜索