
CopyOnWriteArraySet是内置lock锁保证线程安全的去重容器CopyOnWriteArraySet
结构图:
如何保证线程安全源码如下:
public class CopyOnWriteArrayList{ final transient ReentrantLock lock = new ReentrantLock(); private transient volatile Object[] array; }
集合的本质是一个变长的数组,使用volatile修饰;add remove等操作方法使用ReentrantLock保证线程安全
add操作源码如下:
public class CopyOnWriteArrayListSystem.arraycopy()方法{ // 获得数组对象 final Object[] getArray() { return array; } 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; // 判断是尾插还是自定义index插入元素 int numMoved = len - index; if (numMoved == 0) // 在数组末尾添加元素情况:原数组元素满了之后copy到新数组,新数组长度为原数组长度+1 newElements = Arrays.copyOf(elements, len + 1); else { // 在此数组中的指定位置插入指定元素:将当前在该位置的元素(如果有)和所有后续元素向右移动(即后面元素索引+1) newElements = new Object[len + 1]; System.arraycopy(elements, 0, newElements, 0, index); System.arraycopy(elements, index, newElements, index + 1, numMoved); } // 在index位置添加新的元素 newElements[index] = element; // 设置为新数组 setArray(newElements); } finally { // 释放锁 lock.unlock(); } } // 设置为新数组 final void setArray(Object[] a) { array = a; } }
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
参数解释:
src:源数组
srcPos:源数组要复制的起始位置
dest:目的数组
destPos:目的数组放置的起始位置
length:复制的长度
注意: