【面试题】我们知道ArrayList是线程不安全,请编写一个不安全的案例并给出解决方案。

(一)、不安全的案例(待补充):
(二)解决方案一:使用CopyOnWriteArrayList代替ArrayList
(1)如下面三张图ArrayList底层其实是一个数组
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

(2)CopyOnWriteArrayList底层数组是用volatile 和 transient修饰的。

private transient volatile Object[] array;

volatile 其中一个作用就是线程的可见性,当一个线程修改一个共享变量时,另外一个线程能立即读到这个修改的值。
(3)分析CopyOnWriteArrayList的add方法源码
在这里插入图片描述

①本质还是用到了锁。
②Object[] elements = getArray();就是获取到底层的数组
点进去看getArray()
在这里插入图片描述

③int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
创建一个新的数组,元素为老数组,长度为老数组+1

关于Arrays的copyOfcopyOf(T[] original, int newLength)
Arrays的copyOf()方法传回的数组是新的数组对象,改变传回数组中的元素值,不会影响原来的数组。
copyOf()的第一个参数是旧的数组,第二个自变量指定要建立的新数组长度,如果新数组的长度超过原数组的长度,则保留数组默认值
④newElements[len] = e;
将add方法的参数放倒数组最后一位(本来新数组也就比旧数组长一位)
⑤setArray(newElements); 将新数组赋值给底层数组
在这里插入图片描述

(4)分析CopyOnWriteArrayList的get方法源码
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

可以看到没有锁的存在。
(5)add 方法执行到setArray(newElements)一个注意点(一个介绍视频中说的)
由于数组是volatile,所以更新之后读线程立马可以读到最新数据,但是由于还没有到释放锁的代码,所以此时其他线程不能更新数据。
(6)CopyOnWriteArrayList设计上的优点
对CopyOnWriteArrayList是读写分离的思想,我们刚才看底层也看到读写的其实是不同的数组。
(7)我有一个问题CopyOnWriteArrayList与Collections.synchronizedList有什么区别,对于此问题找到一个【CopyOnWriteArrayList与Collections.synchronizedList的性能对比】博客还没看。链接贴在下面。
https://blog.csdn.net/yangzl2008/article/details/39456817

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值