Java集合(一) CopyOnWriteArrayList
CopyOnWriteArrayList 类分析
1. CopyOnWriteArrayList 其中底层实现存放数据是一个Object数组:
private volatile transient Object[] array;
2. CopyOnWriteArrayList 集合操作,当对集合中的元素进行修改添加或者替换删除(增删改)的时候都是用一个全局的 ReentrantLock lock锁进行控制线程安全的:
transient finall ReentrantLock lock = new ReentrantLock();
3. 创建其对象,默认设置一个长度为0的数组,赋值给array变量。
public CopyOnWriteArrayList() {
setArray(new Object[0]);
}
4. 每次添加元素都创建一个新的数组,将原数组的数据复制到新的数组中,将新添加的元素放在新数组的末尾,重新将新数组赋值给 array , 代码如下:
public boolean add(E e) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len + 1); newElements[len] = e; setArray(newElements); return true; } finally { lock.unlock(); } }
5. 因为存放数据的Object[] array 为volatile 类型的,所以在取数据的时候,没有加 lock锁。
6. 在此类中set方法中涉及到 happens-before 原则的代码如下:
public E set(int index, E element) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); E oldValue = get(elements, index); if (oldValue != element) { int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len); newElements[index] = element; setArray(newElements); } else { // Not quite a no-op; ensures volatile write semantics setArray(elements); } return oldValue; } finally { lock.unlock(); } }
关键代码在else代码块,重新到主内存中取了次链表中的元素。
7. 相关类CopyOnWriteArraySet内部实现是一个CopyOnWriteArrayList,代码如下:
private final CopyOnWriteArrayList<E> al; /** * Creates an empty set. */ public CopyOnWriteArraySet() { al = new CopyOnWriteArrayList<E>(); }
完。。。