ConcurrentModificationException异常原因和解决方法

发布时间 2023-09-08 18:41:32作者: oktokeep

ConcurrentModificationException异常原因和解决方法

public static void main(String[] args) {
    List<Integer> list = new ArrayList<Integer>(){
        {
            add(1);
            add(2);
            add(3);
        }
    };
    Iterator<Integer> iterator = list.iterator();
    while (iterator.hasNext()) {
        iterator.next();
        list.add(4);
    }
}

ConcurrentModificationException 中文意思就是并发修改异常,存在于并发使用 Iterator 时出现的时候,那这个异常是为什么会出现的呢?这个涉及到 fast-fail 机制(快速失败),可以提前预料遍历失败情况,防止数组越界异常。

2种解决办法:
在使用iterator迭代的时候使用synchronized或者Lock进行同步;
使用并发容器CopyOnWriteArrayList代替ArrayList和Vector。

package com.example.core.mydemo.java;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class TestThread {
    public static void main(String[] args) {
//        List<Integer> list = new ArrayList<Integer>(){
//            {
//                add(1);
//                add(2);
//                add(3);
//            }
//        };
//        Iterator<Integer> iterator = list.iterator();
//        while (iterator.hasNext()) {
//            iterator.next();
//            list.add(4);
//        }

        //解决1
//        CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<Integer>(){
//            {
//                add(1);
//                add(2);
//                add(3);
//            }
//        };
//        Iterator<Integer> iterator = list.iterator();
//        while (iterator.hasNext()) {
//            iterator.next();
//            list.add(4);
//        }

        //解决2
//        List<Integer> list = new ArrayList<Integer>(){
//            {
//                add(1);
//                add(2);
//                add(3);
//            }
//        };
//
//        List<Integer> result = new ArrayList<Integer>();
//        Iterator<Integer> iterator = list.iterator();
//        while (iterator.hasNext()) {
//            int id = iterator.next();
//            //或者新增集合来接收。而不要在一个集合中处理
//            result.add(id);
//        }
//        //逻辑调整,放在循环体的外面,或者新增集合来接收。
//        list.add(4);

        //解决3,不使用 iterator
//        List<Integer> list = new ArrayList<Integer>(){
//            {
//                add(1);
//                add(2);
//                add(3);
//            }
//        };
//
//        for (int i = 0; i < 3; i++) {
//            System.out.println(list.get(i)+"");
//            list.add(4);
//
//        }

        //情况4 在使用iterator迭代的时候使用synchronized或者Lock进行同步??
        List<Integer> list = new ArrayList<Integer>(){
            {
                add(1);
                add(2);
                add(3);
            }
        };

        List<Integer> list2 =  Collections.synchronizedList(list) ;

        Iterator<Integer> iterator = list2.iterator();
        //加锁,会报错
        synchronized (iterator) {
            while (iterator.hasNext()) {
                iterator.next();
//                list2.add(4);
            }
        }
    }
    
}