前言
作为java.util.concurrent包下的一员,CopyOnWriteArrayList是支持并发的List。但是,从它的名称我们就可以大体意识到,每当这个List发生了修改的时候,将会重新copy一份。无疑,CopyOnWriteArrayList适合读操作远远多于写操作的情况。
CopyOnWriteArrayList用于实现并发的策略很简单:在初始化后,存储值的数组Object[] array便被赋值,每当发生修改的时候,一个新的数组将会赋值给array,并且旧数组并不会被修改。再加上Iterator虽然基于创建时的array,但不支持修改操作(如set/remove/add),所以所有曾经被复制给array的数组,在某种意义上,都是创建时便确定的不可变对象。而不可变对象,总是线程安全的。
导航
构造方法
相对于ArrayList,CopyOnWriteArrayList由于采取了“写入即复制”的策略,所以不需要进行容量的设置以及扩容处理。
1 | // volatile修饰,保证copy时的可见性 |
add/remove
作为修改操作,CopyOnWriteArrayList会将array重新赋值。当热,这个过程中免不了加锁。
1 | final transient Object lock = new Object(); |
removeAll
addAll实现思路与add相似,这里不再多说。我们来看一下removeAll方法:
1 | public boolean removeAll(Collection<?> c) { |
iterator
注意到COWIterator基于创建时的array,所以无法获得最新的数据。
1 | public Iterator<E> iterator() { |
subList
subList基于array,所以当通过subList获取原list的子视图后,若原list发生了修改,调用子视图方法将会抛出ConcurrentModificationException异常:
1 | public static void main(String[] args) { |