1. 程式人生 > >java.util.ConcurrentModificationException的解決辦法

java.util.ConcurrentModificationException的解決辦法

大家應該都知道, 在java中, 在對一些集合迭代的過程中對集合進行一些修改的操作, 比如說add,remove之類的操作, 搞不好就會拋ConcurrentModificationException,

前幾天在專案中,終於碰到了這個異常。

在單執行緒操作的情況下,在DAO層查詢到資料集合後,返回到service層做業務處理,要求:遍歷資料集合,判斷不符合條件的元素,做刪除操作。

在用foreach和 Iterator 都會發生java.util.ConcurrentModificationException。

看一下JavaDoc對java.util.ConcurrentModificationException異常的描述: 當方法檢測到物件的併發修改,但不允許這種修改時,丟擲此異常。

檢視原始碼後終於發現了原因是因為:

迭代器的modCount和expectedModCount的值不一致。

單執行緒中該異常出現的原因是:對一個集合遍歷的同時,有對該集合進行了增刪的操作。導致AbstarctList的modCount和expectedModCount的值不一致。

而我們要做的就是將需要操作的元素放到中間元素中,並記錄操作標誌位。在遍歷結束後進行增刪操作。

或自定義迭代器複寫其中的相關操作,在操作結束後新增expectedModCount = modCount;

多執行緒中更容易出現該異常,當你在一個執行緒中對一資料集合進行遍歷,正趕上另外一個執行緒對該資料集合進行增刪操作。

解決方案: 1)在使用iterator迭代的時候使用synchronized或者Lock進行同步;

2)使用併發容器CopyOnWriteArrayList代替ArrayList和Vector。

以下是Demo:

推薦大家

1、使用for迴圈進行遍歷集合,在for迴圈中做增刪操作。

2、用Iterator遍歷,使用iterator.remove().

package com.utils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @Author Libin
 * @Date Create in 16:02 2018/7/7
 * @Modified By:
 */
public class Test {
    // 出現java.util.ConcurrentModificationException
    public List<String> m1(List<String> list) {
        for (String temp : list) {
            if ("3".equals(temp)) {
                list.remove(temp);
            }
        }
        return list;

    }

    public List<String> m2(List<String> list) {
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String temp = iterator.next();
            if ("2".equals(temp)) {
                //list.remove(temp);// 出現java.util.ConcurrentModificationException
                iterator.remove();// 推薦使用
            }

        }
        return list;

    }
    //successful!
    public List<String> m3(List<String> list) {
        for (int i = 0; i < list.size(); i++) {
            if ("2".equals(list.get(i))) {
                list.remove(i);
            }
        }
        return list;

    }
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("1");
        list.add("2");
        list.add("3");
        Test test = new Test();
        List<String> listTemp = test.m2(list);
        System.out.println(listTemp.toString());
    }
}

List<Map>,遍歷,刪除資料也會報這個錯。