public class CopyOnWriteArrayList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
final transient ReentrantLock lock = new ReentrantLock();
private transient volatile Object[] array;
/**
* Gets the array. Non-private so as to also be accessible
* from CopyOnWriteArraySet class.
*/
// 获取数组
final Object[] getArray() {
return array;
}
/**
* Sets the array.
*/
// 设置数组
final void setArray(Object[] a) {
array = a;
}
public CopyOnWriteArrayList() {
setArray(new Object[0]);
}
@SuppressWarnings("unchecked")
private E get(Object[] a, int index) {
return (E) a[index];
}
public E get(int index) {
return get(getArray(), index);
}
// 改
public E set(int index, E element) {
final ReentrantLock lock = this.lock; // 创建锁对象
lock.lock(); // 上锁 保证操作的原子性
try {
Object[] elements = getArray(); // 获取原始数组
E oldValue = get(elements, index); // 获取原始数组的值 get(原始数组,元素下标)
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(); // 释放锁
}
}
// 增 不指定下标
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); // 通过复制原始数组 从而创建新的数组 长度+1 为新增加的元素留位置
newElements[len] = e; // 将新增的元素放入
setArray(newElements); // 指向新数组
return true;
} finally {
lock.unlock(); // 释放锁
}
}
// 增 指定下标
public void add(int index, E element) {
final ReentrantLock lock = this.lock; // 创建锁对象
lock.lock(); // 上锁
try {
Object[] elements = getArray(); // 获取原始数组
int len = elements.length; // 获取原始数组的长度
if (index > len || index < 0)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+len);
Object[] newElements; // 创建新数组对象
int numMoved = len - index; // 计算出 从新增的元素 的后半段长度
if (numMoved == 0)
newElements = Arrays.copyOf(elements, len + 1); // 通过复制来创建新数组
else {
newElements = new Object[len + 1];
System.arraycopy(elements, 0, newElements, 0, index);// 复制前半段
System.arraycopy(elements, index, newElements, index + 1,
numMoved); // 复制后半段
}
newElements[index] = element; // 增加新增元素
setArray(newElements); // 指向新数组
} finally {
lock.unlock(); // 释放锁
}
}
// 删 指定下标
public E remove(int index) {
final ReentrantLock lock = this.lock; // 创建锁对象
lock.lock(); // 上锁
try {
Object[] elements = getArray(); // 获取原始数组
int len = elements.length; // 获取原始数组的长度
E oldValue = get(elements, index);
int numMoved = len - index - 1; // 计算出 从删除的元素 的后半段长度
if (numMoved == 0)
setArray(Arrays.copyOf(elements, len - 1)); // 通过复制来创建新数组 去掉删除的元素的总长度
else {
Object[] newElements = new Object[len - 1];
System.arraycopy(elements, 0, newElements, 0, index); // 复制前半段
System.arraycopy(elements, index + 1, newElements, index,
numMoved); // 复制 后半段
setArray(newElements); // 指向新数组
}
return oldValue;
} finally {
lock.unlock(); // 释放锁
}
}
// 删 删除片段
void removeRange(int fromIndex, int toIndex) {
final ReentrantLock lock = this.lock; // 创建锁对象
lock.lock(); // 上锁
try {
Object[] elements = getArray(); // 获取原始数组
int len = elements.length; // 获取原始数组的长度
if (fromIndex < 0 || toIndex > len || toIndex < fromIndex)
throw new IndexOutOfBoundsException();
int newlen = len - (toIndex - fromIndex); // 新数组长度
int numMoved = len - toIndex; // 删除片段至数组末尾的长度
if (numMoved == 0)
setArray(Arrays.copyOf(elements, newlen)); // 指向新数组 (复制的新数组 只到删除前)
else {
Object[] newElements = new Object[newlen]; // 创建新数组对象
System.arraycopy(elements, 0, newElements, 0, fromIndex); // 复制前半段
System.arraycopy(elements, toIndex, newElements,
fromIndex, numMoved); // 复制后半段
setArray(newElements); // 指向新数组
}
} finally {
lock.unlock(); // 释放锁
}
}
// 删 删除所有
public boolean removeAll(Collection<?> c) {
if (c == null) throw new NullPointerException(); //
final ReentrantLock lock = this.lock; // 创建锁对象
lock.lock(); // 上锁
try {
Object[] elements = getArray(); // 获取原始数组
int len = elements.length; // 获取原始数组的长度
if (len != 0) {
// temp array holds those elements we know we want to keep
int newlen = 0;
Object[] temp = new Object[len]; // 创建新数组temp
for (int i = 0; i < len; ++i) { // 遍历原始数组
Object element = elements[i];
if (!c.contains(element)) // 如果被删除的集合元素中包不含这个元素
temp[newlen++] = element; // 将这个元素加入新数组
}
if (newlen != len) { // 如果不等于原始数组的长度
setArray(Arrays.copyOf(temp, newlen)); // 指向复制的新数组
return true;
}
}
return false;
} finally {
lock.unlock();
}
}
// 清除数组内容
public void clear() {
final ReentrantLock lock = this.lock; // 创建锁对象
lock.lock(); // 上锁
try {
setArray(new Object[0]); // 指向新创建的空数组
} finally {
lock.unlock(); // 释放锁
}
}
// 增
public boolean addAll(Collection<? extends E> c) {
Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ?
((CopyOnWriteArrayList<?>)c).getArray() : c.toArray(); // 获取新增数组的内容
if (cs.length == 0) // 新增数组的长度
return false; // 长度为0 增加失败
final ReentrantLock lock = this.lock; // 创建锁对象
lock.lock(); // 上锁
try {
Object[] elements = getArray(); // 获取原始数组
int len = elements.length; // 获取原始数组的长度
if (len == 0 && cs.getClass() == Object[].class)
setArray(cs); // 指向新增的数组
else {
Object[] newElements = Arrays.copyOf(elements, len + cs.length); // 创建新数组 长度为原始数组 + 新增数组 的长度和
System.arraycopy(cs, 0, newElements, len, cs.length); // 复制
setArray(newElements); // 指向新数组
}
return true;
} finally {
lock.unlock(); // 释放锁
}
}
// 排序
public void sort(Comparator<? super E> c) {
final ReentrantLock lock = this.lock; // 创建锁对象
lock.lock(); // 上锁
try {
Object[] elements = getArray(); // 获取原始数组
Object[] newElements = Arrays.copyOf(elements, elements.length); // 通过复制原始数组来创建新数组
@SuppressWarnings("unchecked") E[] es = (E[])newElements;
Arrays.sort(es, c); // 对新数组进行排序
setArray(newElements); // 指向新数组
} finally {
lock.unlock(); // 释放锁
}
}
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
List<?> list = (List<?>)(o);
Iterator<?> it = list.iterator();
Object[] elements = getArray();
int len = elements.length;
for (int i = 0; i < len; ++i)
if (!it.hasNext() || !eq(elements[i], it.next()))
return false;
if (it.hasNext())
return false;
return true;
}
public int hashCode() {
int hashCode = 1;
Object[] elements = getArray();
int len = elements.length;
for (int i = 0; i < len; ++i) {
Object obj = elements[i];
hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
}
return hashCode;
}
}
CopyOnWriteArrayList核心源码阅读
最新推荐文章于 2024-07-27 15:45:10 发布