ArrayList 是不支持多个线程同时进行操作的。
ArrayList 的一个线程安全的变体,其中所有可变操作(add、set 等等)都是通过对底层数组进行一次新的复制来实现的。
CopyOnWriteArrayList 的增删改是在copy的副本上进行的,并且进行操作时使用了ReentrantLock进行了lock操作,此操作不会影响对原来数组的读,故CopyOnWriteArrayList是能够进行并发读的。
并且由于读是没有上锁的,故读操作和写操作没有偏序关系,为了使得写操作对读操作是可见的,因此 elementData 使用 volalite 进行修饰。
CopyOnWriteArraySet 底层使用CopyOnWriteArrayList存储数据。
添加时使用了addIfAbsent和addAllAbsent方法来保证CopyOnWriteArrayList元素的唯一性。
addIfAbsent(E e) 方法未加锁,发现存在于snapshot后就直接返回。
不存在于snapshot时调用私有的addIfAbsent(E e, Object[] snapshot) 方法,该方法有加锁。
这是一种典型的compare-add用法。
addAllAbsent 方法从一开始就进行了加锁操作。
addIfAbsent 和 putIfAbsent 机制
List使用add方法 , Map使用put方法