您的位置 首页 java

快速学习Java中的CopyOnWrite集合

CopyOnWrite集合还是比较简单的,这里做一个简单的介绍。

基础概念

CopyOnWrite翻译过来就是在写的时候才复制,写入时复制是计算机程序设计领域中的一种优化策略。主要思路是 如果有多个调用者同时要求相同的资源,他们会共同获取相同的指针指向相同的资源 直到某个调用者 视图 修改资源内容时,系统才会真正复制一份专用副本给该调用者 而其他调用者所见到的最初的资源仍然保持不变 。这过程对其他的调用者都是透明的。此做法主要的优点是如果调用者没有修改资源,就不会有副本被创建,因此多个调用者只是读取操作时可以共享同一份资源。

Java 中CopyOnWrite集合只有两个类CopyOnWriteArrayList、CopyOnWriteArraySet,而CopyOnWriteArraySet是基于CopyOnWriteArrayList实现的,所以我们只用看看CopyOnWriteArrayList的实现就能清楚CopyOnWrite的实现了。

CopyOnWriteArrayList基础结构

首先是基础属性,直接看源码,如下图:

快速学习Java中的CopyOnWrite集合

可以看到结构还是比较简单的,一个Reentrant lock 的锁lock和一个transient与volatile修饰的Object数组array。lock保证 线程安全 介绍后面的方法会用到,array用来保存数据。

添加方法

添加数据的方法有两类分别为set和add方法,源码如下图:

快速学习Java中的CopyOnWrite集合

两个方法流程比较相似,都是先获取到锁,然后复制出一个数组新的数组,set方法的新数组长度不变,add方法新数组长度加1,,set方法是更新新数组的指定位置元素,add方法是把数据添加到新数组的最后,在最后在把新数组设置给array属性。

移除方法

移除方法也分两个,一个是移除指定索引处的元素,一个是移除指定对象的元素,首先是指定索引的方法,源码如下图:

快速学习Java中的CopyOnWrite集合

移除指定索引方法还是比较简单的,仍然是先获取到锁,然后判断索引位置,如果是最后一个元素,则只用把旧数组中从0到倒数第二个的元素复制到新的数组中就行了。如果不是最后一个旧数组按索引位置分段复制到新数组就行。

移除指定对象的方法稍微复杂一点,源码如下图:

快速学习Java中的CopyOnWrite集合

首先获取到array的快照,再找到对象在数组中的位置,最后才加锁找到对象在最新的array中的位置,根据位置分段进行复制。

总结

这里只分析了更新数据的主要方法,因为查询方法不涉及到加锁和数组的变化整体都比较简单,所以就不去介绍了。

主要是通过分析这几个方法来深入理解CopyOnWrite的思想,通过源码分析发现查询方法都没有加锁,更新方法都加了锁,并且每次更新都是先复制一份,然后在准备好后再更新array ,所以新增进去的数据可能不会及时的读到

所以CopyOnWrite容器只能保证数据的最终一致性,但是不能保证数据的实时一致性 。不过CopyOnWrite容器比较适用于那些读多写少的场景。

Java程序员日常学习笔记,如理解有误欢迎各位交流讨论!

文章来源:智云一二三科技

文章标题:快速学习Java中的CopyOnWrite集合

文章地址:https://www.zhihuclub.com/199973.shtml

关于作者: 智云科技

热门文章

网站地图