美文网首页Android
ArrayList详解(线程不安全,源码分析)

ArrayList详解(线程不安全,源码分析)

作者: Freeala | 来源:发表于2019-08-01 10:19 被阅读0次

    ArrayList线程不安全

    不安全事例代码

     public static void main(String[] args) {
            final ArrayList<Integer> arrayList = new ArrayList<>();
            for(int i=0;i<10000;i++){
                final int a = i;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        arrayList.add(a);
                        System.out.println(a);
                    }
                }).start();
            }
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for(int i=0;i<arrayList.size();i++){
                System.out.println(arrayList.get(i));
            }
            System.out.println("================ size = " + arrayList.size());
        }
    

        结果:

    1564621300(1).jpg

    发现缺少了两条数据,插入数据总个数10000,结果遍历只显示有9998条数据

    不安全原因

    1564574479(1).jpg

        查看源代码可以了解到ArrayList插入数据的方法分两步,第一步是扩容集合长度,第二步放入数据。当我们多个线程同时进行插入数据的操作时,某个线程执行了第一步,扩大了集合大小,同时另一个线程正好也执行了这一步,又扩大了一级,此时会产生新的数组对象,最后两个同时执行赋值的时候,赋值位置正好都在size上,那么此时会发现在一个位置,而两次扩容生成的对象不同,所以后执行赋值的会把之前的覆盖掉。

    解决办法

    • List<String> list = Collections.synchronizedList(new ArrayList<>());
    • 使用其他安全的来代替

    ArrayList源码分析

        ArrayList实际上就是对数组进行不断的扩容,初始默认长度为10。

    1564575992(1).jpg

        每次执行add方法,相当于为数组对应位置赋值,有一个全局变量SIZE,初始化为0,每次赋值都为size位置上赋值,之后size加1。

        ArrayList实例化的时候允许我们传入初始化数组大小,默认是10,。所以当我们知道要插入数据的总个数时候,可以在初始化的时候直接定义list的大小,这样可以防止每次插入数据的时候总会复制数组浪费资源。

    1564623587(1).jpg

        执行add方法时候,分两步,第一步判断是否数组需要扩容第二步插入数据。其中第一步会执行到grow方法,在该方法中进行数组的扩容。

    1564623822(1).jpg

        在执行grow进行数组扩容之前,还会先经历三个ensureCapacityInternal 来确定是否需要扩容,以及扩容多少,按照现在它的算法,每次扩容会扩原数组一半大小,即原长度为9,则扩容后为9+4=13。

    1564623993(1).jpg
    • arraylist 是可以查找第一个null的位置的,请看源码
    1564622508(1).jpg

    相关文章

      网友评论

        本文标题:ArrayList详解(线程不安全,源码分析)

        本文链接:https://www.haomeiwen.com/subject/seafdctx.html