概述
CopyOnWriteArrayList是java.util.concurrent包中的一员,是ArrayList的线程安全版本。其实现原理正如它的类名描述的一样,在进行修改的时候,复制一份数据为新数组,并在新数组上面修改,最后将原来的数组引用指向新数组。
构造方法
CopyOnWriteArrayList拥有三个构造函数,分别是空参构造、传递一个集合的构造、传递一个数组的构造,下面对这三个构造函数一一讲解
public CopyOnWriteArrayList()
1 | /** |
空参构造就是创建了一个新的长度为0的Object数组,并且将该数组赋值给使用volatile修饰的成员变量array
1 | private transient volatile Object[] array; |
public CopyOnWriteArrayList(Collection<? extends E> c)
1 | /** |
该构造方法首先将集合转换为数组,然后赋值给成员变量array。
public CopyOnWriteArrayList(E[] toCopyIn)
1 | /** |
给构造方法是将传递进来的数组通过拷贝的方式复制到Object数组,然后赋值给成员变量array。
方法解析
add()
1 | /** |
remove()
1 | /** |
get()
1 | public E get(int index) { |
get()的实现很简单,就是返回”volatile数组“中的第index个元素。
iterator()
1 | public Iterator<E> iterator() { |
- 创建迭代器的时候, 会保存数组元素的快照(有一个引用指向原数组)。
- COWIterator不支持修改元素的操作。例如,对于remove(), set(), add()操作都会抛出UnsupportedOperationException!
总结
1.CopyOnWriteArrayList是线程安全的,通过volatile和互斥锁以及写时复制保存线程安全。
2.修改操作(add、remove、set等)由于需要拷贝数组,性能损耗相对比较大。
3.使用迭代器进行遍历的速度很快,并且不会与其他线程发生冲突。迭代过程如果有修改操作会抛出UnsupportedOperationException,而不是ConcurrentModificationException,所以CopyOnWriteArrayList没有fail-fast机制。