当前位置:网站首页>ArrayList线程不安全和解决方案

ArrayList线程不安全和解决方案

2022-07-07 08:23:00 HGW689

我们通常说的Java中的fail-fast机制(快速失败机制),默认指的是Java集合中的一种错误检测机制,当多个线程对集合进行结构性的改变时,有可能会出发fail-fast机制,这个时候会抛出ConcurrentModificationException异常。
在这里插入图片描述
为什么ArrayList线程不安全?Vector却线程安全呢?让我们来一探究竟!
ArrayList:

    public boolean add(E e) {
    
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        //ensureCapacityInternal()就是判断如果将当前的新元素加到列表后面,列表的elementData数组的大小是否满足,如果size + 1的这个需求长度大于了elementData这个数组的长度,那么就要对这个数组进行扩容
        elementData[size++] = e;
        return true;
    }

Vector:

    public synchronized boolean add(E e) {
    
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }

显而易见:在ArrayList中,elementData与size都是全局变量,但没有进行sychronization同步处理,elementData是共享的线程不安全的mutable可变数据。

那么如何解决LIst线程安全问题呢?

  1. Vector:Vector list = new Vector<>();
  2. Collections:List list = Collections.synchronizedList(new ArrayList());
  3. CopyOnWriteArrayList:List list = new CopyOnWriteArrayList<>();

我们来看看 CopyOnWriteArrayList 中的add()方法,原理是使用了 写时复制技术:

    public boolean add(E e) {
    
        final ReentrantLock lock = this.lock;
        // 首先:加锁!
        lock.lock();
        try {
    
            Object[] elements = getArray();
            int len = elements.length;
            // 1、将内容复制了一份
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            // 2、写入新的内容
            newElements[len] = e;
            // 3、合并
            setArray(newElements);
            return true;
        } finally {
    
            lock.unlock();
        }
    }
原网站

版权声明
本文为[HGW689]所创,转载请带上原文链接,感谢
https://blog.csdn.net/m0_49183244/article/details/125430374