ArrayList是常用的Java数据结构,但是在多线程环境下ArrayList不是线程安全的类。
线程安全的ArrayList有这些:Vector和CopyOnWriteArrayList。
重点会讲到以下几点:
Copy-On-Write容器介绍
CopyOnWriteArrayList的核心实现
CopyOnWriteArrayList为什么性能高
CopyOnWriteArrayList的使用案例
CopyOnWriteArrayList的优缺点
CopyOnWriteArrayList的应用场景
Copy-On-Write容器(写入时复制)
隐藏内容,您需要满足以下条件方可查看
End
课后作业:
CopyOnWriteArrayList 的底层实现(重点谈谈线程安全部分)?
谈谈CopyOnWriteArrayList 的缺点是什么?
谈谈CopyOnWriteArrayList 与 Vector 比较?
最后谈谈CopyOnWriteArrayList 的典型应用场景?
CopyOnWriteArrayList 的底层实现(重点谈谈线程安全部分)?
读不加锁,写加锁(ReentrantLock),写的时候是新复制一个数组(容器)出来(读线程无感知,照旧在读老数
组),写完成之后,会将数组的引用指向新的数组,数组的引用用volatile来修饰,解决线程之间修改可见性的问
题。
谈谈CopyOnWriteArrayList 的缺点是什么?
1、内容占用问题,每次写数据都需要复制一个新的容器出来
2、是最终一致性,不能保证数据的实时一致性。在写的过程之中,同时存在的读线程还在读原来的数据。
谈谈CopyOnWriteArrayList 与 Vector 比较?
Vector是增删改查都加锁(synchronized),COW是只在增删改上加锁(ReentrantLock独占锁),但是读操作不
加锁,支持并发读。
最后谈谈CopyOnWriteArrayList 的典型应用场景?
读多写少的环境
COW的实现是用内存来换性能,在数组本身占据内存空间较大的情况之下,需要评估使用
细节部分都谈到了 ✗咧嘴笑✗ ✗拳头✗
CopyOnWriteArrayList 的底层实现(重点谈谈线程安全部分)?
底层实现采用了一种写时复制的策略,内部数据结构是一个数组,并用volatile进行了修饰,并发读的时候,无锁竞争,其他线程写时采用采用reentrantlock加独占锁,复制一份当前的数组进行操作,操作完后替换当前的数组,由于是volatile修饰的,读线程能及时感知。
谈谈CopyOnWriteArrayList 的缺点是什么?
CopyOnWriteArrayList由于在增删改的时候,完全复制当前数组,这样如果数组容量比较大的时候,就会非常消耗内存,另外写的时候会加锁,如果并发写比较高的情况下,也不适合。
谈谈CopyOnWriteArrayList 与 Vector 比较?
vector的读写操作方法上加了synchronized,导致多线程下并发读写也会产生锁竞争,相对来说,CopyOnWriteArrayList 读是无锁的,写的时候才会加锁,因此CopyOnWriteArrayList 在读多写少的情况下性能会更高
最后谈谈CopyOnWriteArrayList 的典型应用场景?
CopyOnWriteArrayList 是一种写时复制策略,典型应用场景是在读多写少的情况下,并且容量不是很大场合。比如像注册中心中的路由表信息维护,就比较适合这种结构
✗拳头✗