CopyOnWriteArrayList是自JDK5开始提供的支持并发读写的List。从名字可以大致的看出来其内部的设计思想:在写入前copy一份数据以提供修改。下面看一下具体的实现:
基本结构
CopyOnWriteArrayList内部有两个属性:lock表示一把锁,在写入的时候使用;另外一个用于数据存储的array[], 这里是volatile类型的,意思就是当新的array替换时,可以立即生效(多线程可见)。
常用方法
add()
上面代码可以很容易理解:加锁、拷贝数组、释放锁。add完成后,array[]容量+1。
set()
上面代码:加锁、拷贝数组、释放锁。整体流程没什么问题,但是有一点需要说一下的就是:当element和oldValue引用相同时,还是进行了一下setArray()操作。这是因为element如果在外部被改变,其他线程并不能立即知道(因为volatile关键字修饰的是array[])。当调用setArray()重新赋值时,会使array[]整体对其他线程可见。
get()
从上面代码可以看出,get()过程中没有任何的锁操作。所以获取到的值并不能保证实时性。
总结
CopyOnWriteArrayList使用时需要考虑的两个问题是:1、数组拷贝时的内存占用问题;2、数据一致性问题。从上面的方法可以看出来,CopyOnWriteArrayList适合读远大于写的场景。