ArrayList线程安全问题

    • 验证思路
    • 代码展示
    • 程序运行结果
    • 源码分析
    • 总结

验证思路

新建若干个(1000)个线程,一个全局arraylist. 然后往ArrayList中添加东西。 代码和结果见下图

代码展示

//初始化全局的ArrayList
private  List list = new ArrayList<>();
//初始化用于控制线程同时开始的 countDownLatch
private  CountDownLatch countDownLatch = new CountDownLatch(10000); 
  
public void run() {
        //线程重写的run方法
        //每次新建一个Object并添加到list中
        Object object = new Object();
        list.add(object);
        countDownLatch.countDown();
    }
//main函数里面的执行逻辑 
        for (int i = 0; i <10000 ; i++) {
            IS_ArrayVector arrayVector = new IS_ArrayVector();
            Thread thread = new Thread(arrayVector);
            thread.start();
        }

        countDownLatch.await();
        System.out.println(list.size());

程序运行结果

源码分析

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

从ArrayList的源代码可见主要问题出在size++上。

size++分为三步:a.取size值,b.加1,c.再把值赋给size。

在此时,如果两个线程同时执行到 a 步。 假设限得值为2。都分别加1得到结果3,再把3赋给size。 最后size的值为3 。 但实际上是执行了两次add。

总结

在平时的javaWeb开发中可能接触不到多线程的问题,但这种问题不能忽略!为啥?? 面试时升职加薪你要不要??!!
注:需要项目源码的可以扫下方二维码关注我哦
ArrayList线程安全问题_第1张图片

你可能感兴趣的:(java)