ArrayList并发修改异常分析

1.迭代器遍历

Collection list = new ArrayList();
// 添加操作略
Iterator iterator = list.iterator();
while(iterator.hasNext()){
	System.out.println(iterator.next());
}

迭代器是从哪里获得list内数据的?


public class ArrayList{
	// ...
	transient Object[] elementData // 用于存储数据
	// ...
	public Iterator<E> iterator() {
        return new Itr();
    }
    // ...
    private class Itr implements Iterator<E> {
    	 public boolean hasNext() {
            // 判断是否到数组末尾
        }
	    public E next() {
	            // ...
	            Object[] elementData = ArrayList.this.elementData;
	           // ...
	    }
}

ArrayList中有一个数组,用来储存添加的数据。ArrayList实例对象调用iterator方法,可以生成一个内部类Itr的实例对象iterator。iterator每次调用next方法前,都会判断是否还有数据,如果还有就将list数组的数据,拷贝一份到方法内的局部变量储存,然后根据指针取出数据。
所以,迭代器中的数据是直接来自list,而且每次调用next方法前,都会重新获取一次。
2. 迭代器遍历流程图
ArrayList并发修改异常分析_第1张图片在遍历的时候,如果出现对list元素的增删就会导致并发修改异常,如下:

    public static void main(String[] args){
        ArrayList<String> list = new ArrayList<String>();
        list.add("Java");
        list.add("Hello");
        list.add("World");
        Iterator<String> it = list.iterator();//获取迭代器对象
        while(it.hasNext()){ //如果迭代器判断集合中还有下一个元素则继续循环
            String str = it.next();//获取集合中迭代器所指向的元素
            if(str.equals("Java")) {//如果这个元素内容是"Java"
                list.add("Android");//则在集合中添加一个"Android"
            }
        }
    }

控制台输出:

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
    at java.util.ArrayList$Itr.next(ArrayList.java:831)
    at com.itheima.day02.Test5.main(Test5.java:17)

3.如何避免并发修改异常。
可以参考如下博文,https://blog.csdn.net/qq_29534705/article/details/80899351

你可能感兴趣的:(Java,Java基础)