ArrayList多线程环境下不安全,该如何解决问题呢???

4 篇文章 0 订阅
在多线程环境中,ArrayList会出现并发修改异常。解决方法包括使用Vector、Collections.synchronizedList()以及重点推荐的CopyOnWriteArrayList。CopyOnWriteArrayList通过写时复制策略实现线程安全,读写分离,避免在添加元素时阻塞读操作。
摘要由CSDN通过智能技术生成

ArrayList 线程不安全

在多线程得环境下,线程会争抢资源,导致java.util.ConcurrentModificationException 并发修改异常

解决方法:

Vector

将ArrayList 替换成为Vector
原理:
*将指定的元素插入到此Vector的指定位置。
将当前在该位置的元素(如果有的话)和任何后继元素右移(将其索引加一)
源码:

 /**
     * Inserts the specified element at the specified position in this Vector.
     * Shifts the element currently at that position (if any) and any
     * subsequent elements to the right (adds one to their indices).
     *将指定的元素插入到此Vector的指定位置。
     *将当前在该位置的元素(如果有的话)和任何*后继元素右移(将其索引加一)
     * @param index index at which the specified element is to be inserted
     * @param element element to be inserted
     * @throws ArrayIndexOutOfBoundsException if the index is out of range
     *         ({@code index < 0 || index > size()})
     * @since 1.2
     */
    public void add(int index, E element) {
        insertElementAt(element, index);
    }

方法实现

    public synchronized void insertElementAt(E obj, int index) {
        modCount++;
        if (index > elementCount) {
            throw new ArrayIndexOutOfBoundsException(index
                                                     + " > " + elementCount);
        }
        ensureCapacityHelper(elementCount + 1);
        System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
        elementData[index] = obj;
        elementCount++;
    }

Collections.synchronizedList(new ArrayList<>());

原理:将不安全得ArrayList加锁变成线程安全的
一般不用

重点 :CopyOnWriteArrayList

原理
new CopyOnWriteArrayList<>(); 扩容+1,copyof //复制一份,实现读写分离,写的时候加锁
* 源码:CopyOnWriteArrayList 即写时复制容器,往一个容器添加元素的时候,不直接往当前容器 object[]
* 添加,复制出一个新的Object[] newElements, 然后新的容器Object[] newElement 里添加元素,添加元素之后
* 再将原容器的引用指向新的容器 setArray(newElements);这样做的好处是可以对CopyOnwrite容器进行并发的读取
* 而不需要加锁,因为当前容器不会添加任何元素,所以CopyOnwrite容器也是一种读写分离得思想,读和写得容器不同
*
源码

 /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#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();
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值