juc并发05 线程通信-异常演示(arraylist线程不安全)(写时复制技术)

1.为什么arrarlist线程不安全?
我们点开arraylist的add方法可以看见,add方法上是没有synchronized方法的(当然也没有添加lock),因此arraylist是线程不安全的
在这里插入图片描述
由于arratlist底层是一个数组,在我们新增一个元素时,后进行数组扩容,也就会调用源码中的grow()函数进行数组的扩容,但在多线程的情况下,会出现同时扩容同一个数量的数组,就会抛出ConcurrentModificationException异常问题,也就是线程不安全。

2.解决arraylist线程不安全方案

  • 使用Vector方案,其中他的每个方法都添加了synchronized,因此Vector是线程安全的,但是Vector是1.0出现的解决方案,因此目前不常用这个解决方法
  • 使用Collections工具类中的synchronizedList方法
List<String> list = Collections.synchronizedList(new ArrayList<>());
  • CopyOnWriteArrayList(写时复制技术)
    在这里插入图片描述
    上图的解释就是,写时复制,就是当对这个list进行写的操作的时候就进行复制一份一模一样的数据,然后进行合并操作,然后读的时候就进行读合并出来新的那份数据

3.CopyOnWriteArrayList的优缺点
优点:
对于一些 读多写少的数据,这种做法的确很不错,例如配置、黑名单、物流地址等变化非常少的数据,这是一种 无锁的实现。可以帮我们实现程序更高的并发。
缺点:
这种实现只是保证数据的最终一致性,在添加到拷贝数据而还没进行替换的时候,读到的仍然是旧数据。如果对象比较大,频繁地进行替换会消耗内存,从而引发Java的GC问题,这个时候,我们应该考虑其他的容器,例如 ConcurrentHashMap。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值