java aop读写分离_CopyOnWriteArrayList:Java集合中的读写分离

提到读写分离,大家可能首先会想到MySQL的读写分离,也就是在master节点上进行数据库写操作,在slave节点上进行数据库读操作,用这样的手段来提升数据库的性能、稳定性、高并发。其实,在java编程语言中,有一个集合类也贯彻了读写分离的思想,它就是:CopyOnWriteArrayList (另外一个类CopyOnWriteArraySet与此类似)。

一、CopyOnWriteArrayList总体介绍

我们先来看一下此集合类的层级结构:

07b384ed997a1345a3a80fab96bce180.png

在这里插入图片描述

CopyOnWriteArrayList类实现了List接口,是ArrayList一种线程安全的变体,所有的可变操作(增删改等),都是通过复制底层数组来进行的。官方文档说明如下:A thread-safe variant of ArrayList in which all mutative operations (add, set, and so on) are implemented by making a fresh copy of the underlying array.

二、CopyOnWriteArrayList实现原理

通过源码看一下类的底层实现原理,以下是类变量:

//可重入锁,对所有可变操作加锁final transient ReentrantLock lock = new ReentrantLock();//存储数据的数组,保证可见性。只有getArray和setArray方法可以访问private transient volatile Object[] array;

向容器中添加元素的源码如下:

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方法复制到一个新的数组中,添加元素后把新的数组赋值给容器底层的数组,最后释放锁。其它的可变操作,比如删除、元素替换等,实现机制是相同的,都是通过复制一个新的数组来进行的。

读取操作比较简单,直接从数组中获取数据,没有进行加锁:

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

因为写操作总是复制底层数组来进行运算,而读操作直接读取数组中数据,所以这是一种读写分离的形式。当然,因为每次可变操作都要进行数组的复制,这个代价是相当高的,所以CopyOnWriteArrayList比较适合读多写少的场合,比如商品品类,省市区等地址信息等。

三、与ArrayList的对比

既然CopyOnWriteArrayList是ArrayList的变体,那么它们肯定有区别,下面的表格从多个角度对比了两者不一样的地方:

040c603a7815d483011029cf90748384.png

参考资料:http://www.benchresources.net/copyonwritearraylist-vs-arraylist-in-java/

http://www.makeinjava.com/copyonwritearraylist-concurrent-collection-java-example/

欢迎关注微信公众号【互联网全栈架构】,获取更多信息。

712cf31d0ab4a914ad9a1bad8c550131.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值