CopyOnWriteArrayList、CopyOnWriteArraySet是两个线程安全的集合。
1、CopyOnWriteArrayList 底层是一个数组实现的构造函数如下:
public CopyOnWriteArrayList() { array = (E[]) new Object[0]; }array是用volatile 修饰的: private volatile transient E[] array; 线程中具有可见性,add方法使用synchronized关键字修饰,保证线程安全。源码分析如下:
public synchronized boolean add(E element) { int len = array.length;//获取数组的长度 E[] newArray = (E[]) new Object[len+1];//创建一个新数组,容量比原来的数组+1 System.arraycopy(array, 0, newArray, 0, len);//把原来的数组拷贝到新数组 newArray[len] = element;//本次添加的元素添加进新数组的末尾 array = newArray;//把新数组赋值给volatile 修饰的数组 return true; }2、CopyOnWriteArraySet底层实现为CopyOnWriteArrayList ,构造函数如下:
public CopyOnWriteArraySet() { al = new CopyOnWriteArrayList<E>(); }add方法如下:
public boolean add(E o) { return al.addIfAbsent(o); }
public synchronized boolean addIfAbsent(E element) { int len = array.length;//获取数组的长度 E[] newArray = (E[]) new Object[len + 1];//创建一个新数组,容量比原来的数组+1 for (int i = 0; i < len; ++i) { if (element == array[i] || (element != null && element.equals(array[i])))//如果本次添加的元素在数组中存在则直接返回,添加失败 return false; else newArray[i] = array[i];//本次添加的元素如果在数组中不存在则 把原来的数组复制到新数组 } newArray[len] = element; //把本次添加的元素 添加到新数组的末尾 array = newArray; //把新数组赋值给原来的数组 return true; }