SHinny
SHinny

Reputation: 99

Concurrent Modification exception for this code block, Help Please?

missedMSRB is a List with 2187 elements in it and when trying to run the below snippet

List<List<String>> subList = getSubList(missedMSRB, 1000);

    for (List<String> subMSRB : subList) {

        StringBuffer sql = new StringBuffer(NamedQueries.msSQL); 
        sql.append("(");

        for (int i1 = 0; i1 < subMSRB.size(); i1++) {  //Line 463 Throws Exception

            if (i1 < subMSRB.size() - 1) {
                sql.append("?,");
            } else {
                sql.append("? )");

            }

        } ....

Code fails with the follwoing exception any suggestions why i am getting concurrent modification and how to get rid of the same

13 Jan 2015 10:42:58,974 [main] ERROR  RunAnalytics:  General Error: null
java.util.ConcurrentModificationException
    at java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1169)
    at java.util.ArrayList$SubList.size(ArrayList.java:998)
    at com.abc.Analytics.RunAnalytics.getCountCheck(RunAnalytics.java:463)
    at com.abc.Analytics.RunAnalytics.analyticsExecute(RunAnalytics.java:342)
    at com.abc.Analytics.RunAnalytics.main(RunAnalytics.java:84)

Remaining code below

PreparedStatement psMSQL2 = msSQL.prepareStatement(sql.toString());

    psMSQL2.setString(1, runDate);
    psMSQL2.setString(2, runDate2);

    int i = 3;
    for (String s : subMSRB) {
        psMSQL2.setString(i, s.trim());
        i++;
    }

    ResultSet msSQL = psMSQL2.executeQuery();
    logger.debug("SQL executed");

    while (msSQL.next()) {
        missedMSRB.remove(msSQL.getString(1));
    }

getSubList impl// Corrected

public static List<List<String>> getSubList(List<String> inputList, int subListSize) {

        int listSize = inputList.size();
        int noOfLoops = listSize / subListSize;
        int remainingListSize = listSize % subListSize;

        List<List<String>> subList = new ArrayList<List<String>>();

        for (int i = 0; i < noOfLoops; i++) {
            int fromIndex = i * subListSize;
            int toIndex = (fromIndex) + subListSize;
            subList.add(new ArrayList<String>(inputList.subList(fromIndex, toIndex)));

            if ((remainingListSize != 0)
                    && (toIndex == (listSize - remainingListSize))) {
                subList.add(new ArrayList<String>(inputList.subList(toIndex, listSize)));

            }
        }

        return subList;

    }

Upvotes: 0

Views: 1055

Answers (1)

njzk2
njzk2

Reputation: 39406

In getSubList you create several lists using inputList.subList. This method from List implemented in ArrayList does not create a new List. Instead, it returns a view of inputList, and is therefore backed by inputList.

Any modification to inputList has an impact on the sublist. You have passed missedMSRB in as inputList, so any modification to missedMSRB will impact on subList

Therefore, when you call missedMSRB.remove within the outer for loop, you create a ConcurrentModification to all the lists in subList. When you then check the size of one of this lists in subList it throws the ConcurrentModificationException

To solve this, you can for example create a new list instead of using directly the result of subList:

subList.add(new ArrayList<String>(inputList.subList(fromIndex, toIndex)));

Upvotes: 2

Related Questions