解决Collection集合的线程安全问题(List、Set、Map)

线程不安全:

1.    故障现象
          java.util.ConcurrentModificationException
2.   导致原因
          ArrayList线程不安全的,在add的时候并没有加锁,导致多线程add没有执行完时进行了读,导致修改次数不一致,报并发 修改异常
          即:modCount != expectedModCount=false出现的问题集合的修改次数和迭代器的修改次数不一致导致的问题,

3. 解决方案
           //Collections.synchronizedList(new ArrayList<>());
           //new Vector();(弃用)
           //new CopyOnWriteArrayList();(写时复制,读写分离)

list和set一样(CopyOnWriteArrayList、CopyOnWriteSet)

写时复制

CopyOnWrite容器即写时复制的容器。往一个容器添如元素的时候,不直接往当前容器object[]添加,而是先将当前容器object[]进行copy,复制出一个新的容器object[] newElements,然后新的容器object[] newElements 里添加元素,添加完元素之后,再将原容器的引用指向新的容器setArray(newElements);。 这样做的好处是可以对CopyonWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnwrite容器也是一种读写分离的思想,读和写不同的容器

线程安全:

public class NotSafeDemo {
    public static void main(String[] args) {
        //System.out.println(UUID.randomUUID().toString().substring(0, 6));
        List list =new CopyOnWriteArrayList(); //Collections.synchronizedList(new ArrayList<>());//new Vector();//new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0, 6));
                System.out.println(list);
            }, String.valueOf(i)).start();
        }
    }
}

线程不安全:

public class NotSafeDemo {
    public static void main(String[] args) {
        //System.out.println(UUID.randomUUID().toString().substring(0, 6));
        List list =new ArrayList<>();//new CopyOnWriteArrayList(); //Collections.synchronizedList(new ArrayList<>());//new Vector();//
        for (int i = 0; i < 30; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0, 6));
                System.out.println(list);
            }, String.valueOf(i)).start();
        }
    }
}

会报:java.util.ConcurrentModificationException,并发修改异常

ConcurrentHashMap

public class NotSafeDemo {
    public static void main(String[] args) {
        //System.out.println(UUID.randomUUID().toString().substring(0, 6));
        Map<String,String>map=new ConcurrentHashMap<>(); //Collections.synchronizedList(new ArrayList<>());//new Vector();//new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            new Thread(() -> {
               map.put(""+i,UUID.randomUUID().toString().substring(0, 6));
                System.out.println(map);
            }, String.valueOf(i)).start();
        }
    }
}
发布了126 篇原创文章 · 获赞 6 · 访问量 3757

猜你喜欢

转载自blog.csdn.net/qq_40244391/article/details/103617768