我们先来简单分析以下`Vector`的源码。 ### 一、Vector集合源码简析 由于本文的重点不是`Vector`集合,因此只是简单的分析一下`Vector`的初始化方法和添加元素的方法。 `Vector`的底层实现和`ArrayList`一样,都是由数组实现的。 `Vector`的主要变量如下: ```java /** * 存放元素的数组 */ protected Object[] elementData; /** * 元素个数 */ protected int elementCount; /** * 扩容自增容量大小 */ protected int capacityIncrement; ``` #### 1.1 Vector初始化 `Vector`的初始化提供了三个方法,除了可以指定初始容量的大小,还可以指定扩容容量的大小。构造器分别如下: **无参构造器** ```java public Vector() { this(10); } ``` **指定初始化容量的构造器** ```jav public Vector(int initialCapacity) { this(initialCapacity, 0); } ``` **指定初始化容量和扩容容量大小的构造器** ```java public Vector(int initialCapacity, int capacityIncrement) { super(); if (initialCapacity 0) throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity); this.elementData = new Object[initialCapacity]; this.capacityIncrement = capacityIncrement; } ``` 从上面的构造器中可以看出,如果调用无参构造器,则会创建一个初始化容量为`10`,扩容容量为`0`的`Vector`集合。 #### 1.2 如何扩容 `Vector`的扩容机制和`ArrayList`的很像,如果不清楚`ArrayList`的扩容机制,可以看看[这篇文章](
根据名字来看就是**写入时复制**。意思就是大家共同去访问一个资源,如果有人想要去修改这个资源的时候,就需要复制一个副本,去修改这个副本,而对于其他人来说访问得资源还是原来的,不会发生变化。 #### 2.2 初始化CopyOnWriteArrayList `CopyOnWriteArrayList` 底层是也是有数组实现的。 本文我们只解读添加元素和读取元素的区别,删除修改元素原理和添加元素差不多,操作时都需要进行加锁,而读操作不会加锁。 `CopyOnWriteArrayList `主要有以下两个变量: ```java // 独占锁 final transient ReentrantLock lock = new ReentrantLock(); // 存放元素的数组 private transient volatile Object[] array; ``` 我们仔细来分析一下上面两个属性,这两个思想是 `CopyOnWriteArrayList` 的核心 。 - lock:ReentrantLock,独占锁,多线程运行的情况下,只有一个线程会获得这个锁,只有释放锁后其他线程才能获得。 - array:存放数据的数组,关键是被`volatile`修饰了,被`volatile`修饰,就保证了可见性,也就是一个线程修改后,其他线程立即可见。 最常用的初始化方式如下: ```java /** * Creates an empty list. */ public CopyOnWriteArrayList() { setArray(new Object[0]); } /** * Sets the array. */ final void setArray(Object[] a) { array = a; } ``` 初始化只是创建了一个空的数组,并将`array`指向它。 #### 2.3 添加元素 ```java public boolean add(E e) { final ReentrantLock lock = this.lock; lock.lock(); try { // 获取原来的数组 Object[] elements = getArray(); // 原来数组的长度 int len = elements.length; // 创建一个长度+1的新数组,
