CopyOnWriteArrayList
CopyOnWriteArrayList
-
List 不安全
-
并发下的List
//java.util.ConcurrentModificationException 并发修改异常 public class Test03 { public static void main(String[] args) { /*并发下的ArrayList 是不安全的 * */ ArrayList<String> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { new Thread(()->{ list.add(UUID.randomUUID().toString().substring(0,5)); System.out.println(list); },String.valueOf(i)).start(); } } } //Exception in thread "2" Exception in thread "4" Exception in thread "3" Exception in thread "5" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) at java.util.ArrayList$Itr.next(ArrayList.java:851) at java.util.AbstractCollection.toString(AbstractCollection.java:461) at java.lang.String.valueOf(String.java:2981) at java.io.PrintStream.println(PrintStream.java:821) at com.saxon.demo.Test03.lambda$main$0(Test03.java:22)
-
-
查看ArrayList的add底层代码
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } -
查看Vector的add底层代码
public synchronized boolean add(E e) { modCount++; ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = e; return true; }
区别:就加了个synchronized
那JDK为什么不在ArrayList的add加上synchronized呢
并且Vector的出现比ArrayList要早
为了考虑效率问题所以去掉了synchronized
解决方案
//java.util.ConcurrentModificationException 并发修改异常
public class Test03 {
public static void main(String[] args) {
/*并发下的ArrayList 是不安全的
* 解决方案:
* 1、Vector<String> list = new Vector<>(); 不常用
* 2、List<String> list = Collections.synchronizedList(new ArrayList<>());
* 3. List<String> list = new CopyOnWriteArrayList<>(); 推荐
* */
// ArrayList<String> list = new ArrayList<>();
// Vector<String> list = new Vector<>();
// List<String> list = Collections.synchronizedList(new ArrayList<>());
/* CopyOnWrite 写入复制 COW 计算初程序设领域的一种优化策略
* 多个线程调用的时候,List读取的时候,固定的,写入(覆盖)
* 在写入的时候避覆盖,造成数据问题
* CopyOnWriteArrayList比Vector厉害在哪里 看源码*/
List<String> list = new CopyOnWriteArrayList<>();
for (int i = 0; i < 10; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
-
CopyOnWriteArrayList的add方法
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();
}
}
CopyOnWriteArrayList比Vector厉害在哪里?
- Vector是增删改查方法都加了synchronized保证同步,但是每个方法执行的时候都要去获得锁,性能就会大大下降
- 而CopyOnWriteArrayList 只是在增删改上加锁,但是读不加锁,在读方面的性能就好于Vector,CopyOnWriteArrayList支持读多写少的并发情况,读写分离,写时复制出一个新的数组,完成插入、修改或者移除操作后将新数组赋值给array

浙公网安备 33010602011771号