首页 > 其他 > 详细

集合类list不安全

时间:2020-05-15 23:44:07      阅读:64      评论:0      收藏:0      [点我收藏+]

在多线程的情况下使用ArrayList进行读写的时候会出现java.util.ConcurrentModificationException,称为并发修改异常。

代码如下

public class NotSafeDemo {

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

导致ArrayList不安全的原因

  add是没有加锁的

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

 

解决方案: 

  1. 使用Vector(不建议)
  2. 使用Collections.synchronizedList(new ArrayList());
  3. 使用java.util.concurrent包下的CopyOnWriteArrayList;

小总结:

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

 

集合类list不安全

原文:https://www.cnblogs.com/fengyangcai/p/12897790.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!