自己的博客地址:http://www.lixiang.red/tech/java/2018/02/05/arrayList-mutiThread.html
欢迎点击,更多好技术好文在等着您!
验证思路
新建若干个(1000)个线程,一个全局arraylist. 然后往ArrayList中添加东西。 代码和结果见下图
代码展示
//初始化全局的ArrayList
private List<Object> 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());
程序运行结果
[图片上传失败...(image-44fc15-1517832743106)]
源码分析
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开发中可能接触不到多线程的问题,但这种问题不能忽略!为啥?? 面试时升职加薪你要不要??!!
注:需要项目源码的可以扫下方左侧二维码关注我哦
网友评论