CopyOnWriteArrayList使用应该注意的地方

ArrayList是我们在java编程中经常用到的数据集合类,我们也知道ArrayList是非线程安全的,那么当我们在多线程环境下怎样使用ArrayList呢?

第一种方法:使用Synchronized来同步所有的ArrayList操作方法,JDK工具类为我们提供了Collections.synchronizedList()方法免去我们自己实现同步的过程。底层也是在集合的所有方法之上加上了synchronized。

第二种方法:使用CopyOnWriteArrayList,这个类也是JDK为我们提供的。使用方式基本只需把ArrayList实例化的地方改成CopyOnWriteArrayList即可。但是!需要注意以下几点:
1、CopyOnWriteArrayList是写同步,读非同步的。
这个意思就是说多个线程对CopyOnWriteArrayList进行写操作是线程同步的,原因是CopyOnWriteArrayList内部使用了可重入锁,并且在进行修改时,内部先拷贝了一份数据源,再进行操作后,将原数据覆盖,再将可重入锁解锁。
但是读操作get(int index)操作是非线程同步的,如果在for循环中使用下标的方式去读取数据,可能报错ArrayIndexOutOfBoundsException。那么如果需要读取数据应该怎么做?根据源码,用迭代器的方式去获取数据是不会报错的,原因也是在于CopyOnWriteArrayList的内部实现是保存了原来的数据源去迭代,所以使用增强型for循环不会出现异常

另外,一定要注意CopyOnWriteArrayList由于它的迭代器实现了ListIterator接口,但是add() set() remove()方法都直接抛出了UnsupportedOperationException异常,所以应该避免使用迭代器的这几个方法。同时因为迭代器不支持set()方法也就直接导致不支持Collections.sort()进行排序,具体可以看Collections.sort源码,解决方法有两种:如果你的JDK版本在1.8以下,可以将数据源拷贝到ArrayList中,再通过addAll()覆盖到CopyOnWriteArrayList源数据中;如果你使用的JDK版本在1.8及以上,可以直接使用CopyOnWriteArrayList中的sort方法来实现排序。

再有,因为每次使用CopyOnWriteArrayList.add都要引起数组拷贝,所以应该避免在循环中使用CopyOnWriteArrayList.add()。可以在初始化完成后设置到CopyOnWriteArrayList中,或者使用CopyOnWriteArrayList.addAll()方法。

所以大家根据实际情况来选择是否使用CopyOnWriteArrayList。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值