一. 线程不安全的ArrayList
1、为什么说ArrayList是线程不安全的:
add()操作抛出数组越界异常;
add()操作会丢失元素;
set()操作去修改元素,get()操作去获取元素时,可以读到新值也可能读到旧值,无法保证一致性。
源码分析:
public boolean add(E e) {
//确定添加元素之后,集合的大小是否足够,若不够则会进行扩容
ensureCapacityInternal(size + 1); // Increments modCount!!
//插入元素
elementData[size++] = e;
return true;
}
场景1:多个线程都没进行扩容,但是执行了elementData[size++] = e;时,便会出现“数组越界异常”;
场景2:因为size++本身就是非原子性的,多个线程之间访问冲突,这时候两个线程可能对同一个位置赋值,就会出现“size小于期望值的结果”;
场景3:迭代器遍历修改报错
ArrayList是线程不安全的集合类,在单线程环境下,使用iterator进行遍历修改的时候会出现 java.util.ConcurrentModificationException并发修改异常,如下
import java.util.*;
public class Test {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("1w");
list.add("2w");
list.add("3w");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String cur = iterator.next();
if(cur=="1w"){
list.remove(cur);
}
System.out.println(cur