线程安全集合:CopyOnWriteArrayList源码分析

目录

一、基本思想

二、源码分析

add()方法

set()方法 

remove()方法

get()方法       

 三、小结

一、基本思想

       首先CopyOnWrite 简称 COW ,是一种用于对集合并发访问的优化策略。基本思想是:当我们往一个集合容器中写入元素时(比如添加、修改、删除),并不会直接在集合容器中写入,而是先将当前集合容器进行Copy复制,复制出一个新的容器,然后在新的容器里写入元素,写入操作完成之后,再将原容器的引用指向新的容器。

        好处是:保证了对 CopyOnWrite 集合容器写入操作时的线程安全,但同时并不会影响进行并发的读取操作。所以 CopyOnWrite 容器也是一种读写分离的思想。CopyOnWriteArrayList 相当于线程安全的 ArrayList ,内部存储结构采用 Object[] 数组,线程安全使用 ReentrantLock 加锁实现,允许多个线程并发读取,但只能有一个线程写入

 

二、源码分析

add()方法

       添加新元素至集合时,会将当前数组Copy复制到新数组,并将新元素添加至新数组,最后替换原数组。执行过程中,使用ReentrantLock加锁,保证线程安全,避免多个线程复制数组。

  

set()方法 

       根据指定下标修改元素值,复制到新数组,在新数组中修改值,最后替换原数组。执行过程中,使用ReentrantLock加锁,保证线程安全,避免多个线程修改数组元素的值。

remove()方法 

        删除指定下标元素。根据指定下标,从原数组中Copy复制其它元素至新数组,最后替换原数组。

get()方法       

       根据指定下标,到原数组中读取元素。读取过程中不加锁,允许多个线程并发读取。但是如果读取的时候,有其它线程向集合中添加新元素,此时仍然读取到的是旧数据。因为添加操作没有对原数组加锁。

 三、小结

CopyOnWriteArrayList具有以下特性:

  1. 在保证并发读取的前提下,确保了写入时的线程安全,使用ReentrantLock加锁;
  2. 由于每次写入操作时,进行了Copy复制原数组,所以无需扩容,复制就是一种简单的扩容;
  3. 适合读多写少的应用场景,比如缓存。由于add()、set() 、 remove()等修改操作需要复制整个数组,所以会有内存开销大的问题。所以在有写操作的情况下,CopyOnWriteArrayList性能不佳,而且如果容器容量较大的话容易造成溢出。
  4. CopyOnWriteArrayList由于只在写入时加锁,所以只能保证数据的最终一致性,不能保证数据的实时一致性。

     以上就是对于线程安全集合:CopyOnWriteArrayList源码分析的分享,如有不当之处还请大家多多评论指正,喜欢文章的可以留下您的关注和点赞,一起学习,一起加油!

  • 23
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值