欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

高并发场景下ArrayList线程不安全问题解析

程序员文章站 2022-05-21 11:56:32
高并发场景下ArrayList线程不安全问题解析1.在高并发下ArrayList存在并发修改异常package com.example.demo;import java.util.ArrayList;import java.util.List;import java.util.UUID;import java.util.concurrent.CopyOnWriteArrayList;/** * Created by Administrator on 2020/7/5. * * @au...

高并发场景下ArrayList线程不安全问题解析
1.在高并发下ArrayList存在并发修改异常

package com.example.demo;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Created by Administrator on 2020/7/5.
 *
 * @author qtx
 */
public class CollectionDemo {
    public static void main(String[] args) {
        List<String> arrayList=new ArrayList<>();
        //java.util.ConcurrentModificationException线程不安全--高并发修改异常
        for (int i = 0; i <30 ; i++) {
            new Thread(()->{
                arrayList.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(arrayList);
            }).start();
        }
    }
}

执行结果:
高并发场景下ArrayList线程不安全问题解析
2.导致的原因:
并发争抢异常,例如当面试时需要签到,当小明同学正在签到时,只写了个小字之后,小红同学就将签到纸抢走,导致小明同学没有完成签到,这就是并发争抢异常。
3.解决方法:
(1).new Vector<>();不推荐
(2). Collections.synchronizedList(new ArrayList<>());不推荐
(3). new CopyOnWriteArrayList();推荐
4.CopyOnWriteArrayList源码解析:

    /**
     * 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();
        }
    }

先加一个lock轻量级的锁,然后复制出一个新的容器Object[] newElements,然后新的容器Object[] newElements里面添加元素,添加元素之后再将原容器的引用指向新的容器 setArray(newElements),这样做的好处是可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素,所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

本文地址:https://blog.csdn.net/u014385267/article/details/107140950