从JDK1.5开始,Java并发包里面提供了使用CopyOnWrite机制实现的并发容器CopyOnWriteArray-List作为主要的并发List,CopyOnWrite的并发集合还包括CopyOnWriteSet,其底层正是利用CopyOnWriteArrayList实现的。所以今天我们以CopyOnWriteArrayList为突破口,来看一下CopyOnWrite容器的特点。
CopyOnWrite的含义
从CopyOnWriteArray List的名字就能看出他是满足CopyOnWrite的ArrayList,CopyOnWrite的意思是说,当容器需要被修改的时候,不直接修改当前容器,而是先将从前容器进行Copy,复制出一个新的容器,然后修改新的容器,完成修改之后,再将原容器的引用指向新的容器。这样就完成了整个修改过程。
适用场景
- 读操作可以尽可能的快,而写操作即使慢一些也没关系:为了将读取的性能发挥到极致,CopyOnWriteArrayList读取是完全不用加锁的,并且写入也不会阻塞读取操作,也就是说你可以在写入的同时进行读取。只有写入和写入之间需要进行同步,也就是不允许多个写入同时发生,所以会更慢一些
- 读多写少:写入本身是拷贝一份出来,会增加资源的消耗,同时多个写入之间需要进行同步,所哟应该尽量少的写入
特点
迭代期间允许修改集合内容:ArrayList在迭代期间如果修改集合的内容,会抛出Concurrent-ModificationException异常的,CopyOnWriteArrayList的迭代器在迭代的时候,如果数组内容被修改了,CopyOnWriteArrayList不会报Concurrent-ModificationException异常,因为迭代器使用的依然是旧数组,只不过迭代的内容可能已经过时了
缺点
- 内存占用问题:因为CopyOnWrite的写时复制机制,所以在进行写操作的时候,内存里会同时驻扎着两个对象的内存,这一点会额外占用内存空间
- 数据一致性问题:由于CopyOnWrite容器的修改是先修改副本,所以这次修改对于其他线程来说,并不是实时看到的,只有在修改完之后才能体现出来。如果你希望写入的数据能马上被其他线程看到,那么CopyOnWrite容器时不适用的