CopyOnWriteArrayList和CopyOnWriteArraySet

对于ArrayList和HashSet集合,都是线程不安全的,在并发操作下会出现问题,报出ConcurrentModificationException(并发修改异常),虽然他们也有对应的线程安全类,例如ArrayList对应有Vector,是线程安全的,但是看了底层源码都知道,Vector类底层的很多方法都是加了synchronized关键字去加锁实现线程安全,这样一来会导致效率非常低下,所以在并发操作下,一般也不会去使用它

集合工具类Collections里面给我们提供了可以将线程不安全的类转换为线程安全的类的一些方法,例如 Collections.synchronizedList 可以将线程不安全的List转换为线程安全的List,例如 List<Integer> list = Collections.synchronizedList(new ArrayList<>()); 底层实现是去创建了SynchronizedList类,而SynchronizedList类是java.util.Collections中的一个静态内部类。之所以能保证线程安全是因为在一些常用的方法处理上使用了同步代码块,比起Vector实现线程安全的好处在于锁的范围更小,效率更高,另外就是可以灵活地指定要锁定的对象,而同步方法只能锁定this或者类的Class对象;同理也有Collections.synchronizedSet将线程不安全的Set转为线程安全的Set以及Collections.synchronizedMap将线程不安全的Map转换为线程安全的Map,原理都是一样的

而在juc并发下,一般会使用CopyOnWriteArrayList来作为ArrayList对应的线程安全类,以及使用CopyOnWriteArraySet来作为HashSet对应的线程安全类

写入时复制(CopyOnWrite,简称COW)思想是计算机程序设计领域中的一种优化策略。意思是对一块内存进行修改时,不直接在原有内存块中进行写操作,而是将内存拷贝一份,在新的内存中进行写操作,写完之后,再将原来指向的内存指针指到新的内存,原来的内存就可以被回收。

CopyOnWriteArrayList和CopyOnWriteArraySet使用了COW的思想,在执行读操作的时候,不加任何锁,因为读操作没有涉及数据的修改,也就不存在线程不安全的问题,所以不加锁可以提高效率,而在执行写操作的时候,并不是直接在原来的数据上进行修改,而是将原来的数据拷贝一份,在这个副本上进行修改,写完之后,再将修改完的副本替换成原来的数据,这样就可以保证写操作不会影响读操作了。也就是说写一半的时候也不会阻塞读操作,因为读的还是原来的数据。另外对于add方法是加了Lock来保证同步的,避免多线程写的时候会 copy 出多个副本。

综上,CopyOnWriteArrayList和CopyOnWriteArraySet适合读多写少的场景,因为读操作不加锁,效率高,而写操作每次要复制一个副本,会占用更多的内存;另外CopyOnWriteArrayList和CopyOnWriteArraySet与传统的线程安全类Vector相比的优势在于:Vector类所有操作(增删改查)都加了锁,而CopyOnWriteArrayList和CopyOnWriteArraySet只在增删改加了锁,读操作不加锁,效率更高

参考文章:https://www.jianshu.com/p/9b6a4d0b94ac

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值