在确保arrayList线程安全的情况下保证其效率

前两天面试遇到的问题,arrayList本身是线程不安全的,但是他的查询快,因为底层是数组,根据下标找很方便,我们想用他的性能,又想保证安全性该怎么处理?

解决方案如下:

方案一: 通过collections.synchronizedList方法将ArrayList转化为线程安全的,相关源码如下:

其中,涉及到get、set、add、remove,indexOf、lastIndexOf,addAll等方法都添加了同步锁synchronized,另外上图中最后一行代码的注解还在告知我们,类似Iterator方法等无法保证线程安全。效率也并不好,感觉跟vector没什么区别。

方案二:

通过CopyOnWriteArrayList方法封装ArrayList

见名知意  通过复制写的操作来进行处理,可以理解为数据库的读写分离 ,对查询get操作不进行加锁处理,对修改,新增方法添加锁

参考源码如下

第一部分:先定义出数组,之后在增删操作的时候对数组进行扩展

第二部分,以add为例,查看处理逻辑

在进行add的时候,分为在数组的最末端添加和指定下标的添加方法

最末端添加的时候,将原数组的长度+1,直接复制返回。

指定下标添加的时候,判断是否为最末端,不是最末端的话将数组通过当前下标分为两部分,前半部分先转换,后半部分将新的元素塞进去,然后返回,并且在方法的开始和结束都有lock锁的处理

之后我们看看查询方法:

并未加锁。

 

在copyOnWrite方法中,我们在查询时的性能,效率一定比方案一好,当然,在进行修改操作的时候并效率其实是一样的。

在开发中并没有十全十美的方法能在保证性能的情况下保证安全,我们只能尽量保证利益最大化,  另外我在方案二中的开头有专门把array这个数组给截出来,是希望自己记住,多线程处理的情况下,共享数据最好添加一个volatitle和transient来保证数据的可见性和安全性。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值