我们都知道,Java中的ArrayList是非线程安全的,这个知识点太熟了,甚至面试的时候都很少问了。
但是我们真的清楚原理吗?或者知道多线程情况下使用ArrayList会发生什么?
前段时间,我们就踩坑了,而且直接踩了两个坑,今天就来扒一扒。
上源码
上代码之前先说下 ArrayList 的 add 逻辑:
- 检查队列中数组是否还没有添加过元素
- 如果是,设置当前需要长度为10,如果否,设置当前需要长度为当前队列长度+1
- 判断需要长度是否大于数组大小
- 如果是,需要扩容,将数组长度扩容1.5倍(第一次扩容会从0直接到10,后续会按照1.5倍的步幅增长)
- 数组中添加元素,队列长度+1
附上代码,有兴趣的可以在看看源码。
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
// 判断数组容量是否足够,如果不足,增加1.5倍,size是当前队列长度
ensureCapacityInternal(size + 1); // Increments modCount!!
// 给下标为size的赋值,同时队列长度+1,下标从0开始
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static