CopyOnWrite容器

故障现象

出现 java.util.ConcurrentModificationException java的并发修改异常。

ArrayList<String> arrayList = new ArrayList<>();
for (int i = 0; i < 20; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0, 8));
                System.out.println(list);
            }, String.valueOf(i)).start();

        }

故障分析

ArrayList没有加锁。
并发争抢修改导致,查考我们的花名册签名情况。
一个人正在写入,另外一个同学过来抢夺,导致数据不一致异常。并发修改异常。

故障解决方案

3.1 new Vector<>();
3.2 Collection.synchronizedList(new ArrayList<>);
3.3 new CopyOnWriteArrayList<>()

优化建议(同样的错误不犯第二次)

笔记

写实复制CopyOnWrite容器即写时复制的容器。往一个容器添加元素的时候,不直接往当前的容器Object[]添加,而是先将当前的容器Object[]进行copy
复制出一个新的容器Object[] newElements,然后新的容器Object[] newElements里添加元素,添加完,再将原容器的引用指向新的容器setArray(newElements);
这样做的好处时可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。
所以CopyOnWrite容器也是一种读写分离的思想,都和写不同的容器
  //出现并发修改异常 ArrayList<String> arrayList = new ArrayList<>();
       // List<String> list = new Vector<String>();
       // List<String> list = Collections.synchronizedList(new ArrayList<>());
        List<String> list =new CopyOnWriteArrayList<>();

        for (int i = 0; i < 20; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0, 8));
                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();
        }

同样CopyOnWriteArraySet也是线程不安全的。

而HashSet是否是安全的呢?

查看源码

public HashSet() {
map = new HashMap<>();
}
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
private static final Object PRESENT = new Object();

其中利用了hashMap的key存储了值,而hashMap的value为一个固定的值new Object()。
原文地址:https://www.cnblogs.com/fengyangcai/p/13693415.html