CopyOnWriteArrayList是Java中线程安全的集合类之一,本文将对CopyOnWriteArrayList的源码进行解析,以帮助理解其原理和使用方式。
CopyOnWriteArrayList是通过读写分离的思想实现线程安全的,即在读操作和写操作时使用不同的数据副本。读操作不会阻塞,而写操作则会创建一个新的数据副本,以保证线程安全。
CopyOnWriteArrayList的内部维护了一个数组,用来存储集合元素。当有写操作时,会创建一个新的数组来执行写操作,并将原数组的内容复制到新数组中。这样就保证了读操作不会受到写操作的影响。
首先,我们来看CopyOnWriteArrayList的构造方法:
public CopyOnWriteArrayList() {
setArray(new Object[0]);
}
public CopyOnWriteArrayList(Collection<? extends E> c) {
Object[] elements;
if (c.getClass() == CopyOnWriteArrayList.class)
elements = ((CopyOnWriteArrayList<?>)c).getArray();
else {
elements = c.toArray();
// 创建一个新的数组并将c中的元素复制到新数组
}
setArray(elements);
}
copyOnWriteArrayList有两个构造方法,一个是无参构造方法,一个是接受一个集合参数的构造方法。无参构造方法会创建一个空数组,而接受集合参数的构造方法会将集合中的元素复制到新数组中。
接下来,我们看下CopyOnWriteArrayList的主要方法。
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();
}
}
add方法会先获取当前数组,然后将数组长度加1,并创建一个新的数组,将原数组的内容复制到新数组中,再将新元素添加到新数组的最后。最后将新数组设置为当前数组。
public E get(int index) {
return get(getArray(), index);
}
private E get(Object[] a, int index) {
return (E) a[index];
}
get方法会直接从当前数组中获取指定位置的元素。
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 {
setArray(elements);
}
return oldValue;
} finally {
lock.unlock();
}
}
set方法也会先获取当前数组,然后将数组中指定位置的元素替换为新元素,并创建一个新数组来保存修改后的内容。
通过以上代码分析,我们可以看出CopyOnWriteArrayList的核心原理是“写时复制”。每次写操作都会创建一个新的数组来执行操作,并将新数组设置为当前数组,从而保证了读操作的线程安全性。
需要注意的是,由于每次写操作都会创建一个新的数组,所以CopyOnWriteArrayList的写操作的性能较低,适用于读操作较多、写操作较少的场景。
总结: CopyOnWriteArrayList通过读写分离的思想实现了线程安全的集合类。其核心原理是“写时复制”,即每次写操作都会创建一个新的数组来执行操作,并将新数组设置为当前数组,以保证线程安全。由于写操作会创建新数组,所以写操作的性能较低,适用于读操作较多、写操作较少的场景。以上就是CopyOnWriteArrayList源码的基本解析。