java并发容器-CopyOnWriteArrayList

本文介绍了CopyOnWrite的基本概念及其实现原理,探讨了其在读多写少并发场景中的优势与局限,并分析了其可能存在的数据一致性和内存占用问题。

1.基本思路

        Copy-On-Write,是一种用于程序设计中的优化策略。基本思路是:从一开始大家都在共享同一个内容,当某个人想修改这个内容的时候,会把真正的内容Copy出去形成一个新的内容,然后再修改,这是一种延时懒惰策略。

       CopyOnWrite容器,即写时复制容器。通俗理解就是,当我们向一个容器中添加元素的时候,不直接向容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后向新的容器里添加元素,添加完元素后再将原容器的应用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。


2.实现原理

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

    transient final ReentrantLock lock = new ReentrantLock();

    private volatile transient Object[] array;             //实际存储数据的数组

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

    final void setArray(Object[] a) 
    {
        array = a;
    }

     由以上代码看出,添加元素实际上就是先复制一份原来的数组,然后直接添加至末尾,再将引用指向新数组。

     

     读数据可以不用加锁,直接读即可

    public E get(int index) 
    {
        return get(getArray(), index);
    }

3.CopyOnWrite应用场景

       Copy用于读多写少的并发场景。比如黑、白名单,商品类目的访问和更新场景。


4.CopyOnWrite缺点

     (1)数据一致性问题

             CopyOnWrite容器只能保证数据的最终一致性,不能保证数据的实时一致性。如果希望写入的数据马上就能读到,就不要使用CopyOnWrite容器

     (2)内存占用问题

             因为CopyOnWrite的写时复制机制,所以在进行写操作的时候,内存里会同时驻扎2个对象,旧的对象和新写入的对象。如果这些对象占用的内存比较大,如果说200M左右,那么再写入100M数据进去,内存就会有300M,那么这个时候很可能会造成频繁的Full GC。

             针对内存占用问题,可以使用压缩容器中元素的方法来减少大对象的内存消耗。如元素全部都是10进制,可以考虑压缩为32或64进制。或者不使用CopyOnWrite容器,而使用其他并发容器,如ConcurrentHashMap




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值