JDK源码系列-CopyOnWriteArrayList实现原理


前言

CopyOnWrite是一种读写分离的思路,写入的时候会对原数组copy一份出来然后再做修改,适用于读多写少的场景,可以最大程度提升读效率。


1、源码解析

1.1、读写分离图示

在这里插入图片描述

1.2、重要属性

  1. lock:用于实现写写互斥的,保证同一时刻只有一个线程在进行修改
  2. array:存储元素的容器,这里使用volatile标注,是为了防止写线程和读线程没有运行在同一个核心上,产生数据变更后不可见的问题。

在这里插入图片描述

1.3、构造函数

  1. 无参构造函数:这里会创建一个空数组
  2. 带参构造函数:如果参数是cow类型的,那么直接赋值,如果不是,那么转成数组然后再对元素进行copy

在这里插入图片描述

1.4、常用方法解析

1.4.1、add(E e)方法解析

  1. 首先进行加锁,避免写写冲突
  2. 对旧数组进行copy,然后再copy出来的数组上插入新元素
  3. copy数组赋值给数组引用,覆盖原数组

在这里插入图片描述

1.4.2、add(int index, E element)方法解析

  1. 首先加锁,避免写写冲突
  2. 获取旧数组,然后对下标做下越界判断。
  3. 对插入的下标位置做判断,如果是最后一个位置那么直接拷贝一个n+1的数组,然后把元素添加到最后,如果是在中间,那么就会分两次进行拷贝,把idx的位置空出来用以插入元素。
  4. 把引用指向新数组,覆盖原有数组
  5. 释放锁

在这里插入图片描述

1.4.3、get(int index) 方法解析

  1. 这里读取是无锁的,直接根据读取数组对应下标的元素
    在这里插入图片描述

1.4.4、remove(int index) 方法解析

  1. 加锁,避免冲突
  2. 根据下标判断删除的是不是最后一个元素,如果是最后一个则直接创建一个n-1的新数组,copy就行了,如果是中间位置,则会进行两次拷贝,第二次拷贝会往前挪动一个位置,这样就把原有idx的位置元素覆盖掉了。

在这里插入图片描述

总结

从上面方法的源码流程可以看出cow也是存在很多的弊端的,因为读写分离,其实我们读取的数据可能不是最新的一份数组,所以不保证实时一致性,只保证最终一致性,而且如果是读写均匀或者写多读少的情况下,那么就会造成存在多份副本数据,这个时候就会造成jvm频繁的GC

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值