第三章 CopyOnWriteArrayList源码解析1

preview
需积分: 0 0 下载量 56 浏览量 更新于2022-08-04 收藏 325KB PDF 举报
CopyOnWriteArrayList是Java集合框架中的一个特殊列表,位于`java.util.concurrent`包下,专为并发编程场景设计。它的核心特性在于写时复制(Copy-On-Write)策略,这使得它在多线程环境下提供了良好的性能表现。当对列表进行修改操作(如添加、删除或设置元素)时,CopyOnWriteArrayList不会直接在原列表上进行操作,而是创建一个新的底层数组,并将原数组的所有元素复制到新数组中,然后在新数组上执行修改操作,最后将新数组设置为原列表的引用。这种机制保证了在并发读取时,其他线程不会受到写操作的影响,提高了并发性能。 CopyOnWriteArrayList有以下特点: 1. **线程安全**:由于其内部的写时复制机制,CopyOnWriteArrayList天生就具备线程安全性,无需额外的同步措施。这意味着多个线程可以同时读取列表,而一个线程进行修改时,不会干扰到其他线程的读取操作。 2. **有序性**:CopyOnWriteArrayList保持了元素的插入顺序,遍历元素时,它们将以添加时的顺序呈现。 3. **允许空值**:CopyOnWriteArrayList允许列表中包含null值。 4. **允许重复数据**:与ArrayList一样,CopyOnWriteArrayList允许列表中存在相同的元素。 5. **效率**:CopyOnWriteArrayList在大部分情况下非常适合读多写少的并发场景。当写操作频繁时,由于频繁复制数组,可能会导致性能下降,此时应考虑其他数据结构,如ConcurrentHashMap。 向CopyOnWriteArrayList添加元素的过程如下: 1. 当调用`add()`方法时,首先检查当前是否有锁(ReentrantLock)。由于CopyOnWriteArrayList使用了final的ReentrantLock,所以确保了锁的不可变性,增强了并发安全性。 2. 获取锁,确保同一时刻只有一个线程能执行修改操作。 3. 检查是否需要扩容。如果当前数组已满,或者在某些情况下,如并发修改时检测到旧数组已被另一个线程修改,会创建一个新的更大容量的数组。 4. 将旧数组的所有元素复制到新数组中。这是CopyOnWriteArrayList的核心步骤,确保了修改操作不会影响到正在进行的读取操作。 5. 在新数组的末尾添加新元素。 6. 释放锁,并更新引用,将新数组设置为列表的底层数组。 7. 如果在复制过程中发现旧数组已经被其他线程修改,则需要再次复制,以确保一致性。 CopyOnWriteArrayList适用于对列表进行迭代而不修改列表,或者需要在并发环境下确保读操作不被写操作中断的情况。然而,对于需要频繁修改列表的场景,CopyOnWriteArrayList的效率可能会低于其他并发控制机制,如使用`synchronized`修饰的ArrayList或使用`Collections.synchronizedList()`创建的同步列表。在选择数据结构时,开发者应根据具体应用场景权衡其优点和潜在的性能成本。