Gaurav
Gaurav

Reputation: 191

java.util.ConcurrentModificationException for multi-threaded Java code

I got ConcurrentModificationException at "String name = (String) keys.next();" line when I ran a java code in multi-threading. The part of the function that caused error is as follows:

 if (inputStr == null)
        return null;

    String tempStr = new String(inputStr);

    Properties props = System.getProperties();
    Iterator keys = props.keySet().iterator();

    while (keys.hasNext()) {
        String name = (String) keys.next();
        String value = props.getProperty(name);

        //Build a pattern and compile it
        String patternStr = "%" + name + "%";
        Pattern pattern = Pattern.compile(patternStr);

        // Replace all occurrences of pattern in input string
        Matcher matcher = pattern.matcher(tempStr);
        tempStr = matcher.replaceAll(value);
    }

The stacktrace detail is as follows:

Caused by: java.util.ConcurrentModificationException at java.util.Hashtable$Enumerator.next(Unknown Source) at com.pb.common.util.ResourceUtil.replaceWithSystemPropertyValues(ResourceUtil.java:350) at com.pb.common.calculator.ControlFileReader.searchAndReplaceWithEnv(ControlFileReader.java:610) at com.pb.common.calculator.ControlFileReader.readMatrixDataEntries(ControlFileReader.java:493) at com.pb.common.calculator.ControlFileReader.(ControlFileReader.java:109) at misc.UtilityExpressionCalculator.(UtilityExpressionCalculator.java:191) at misc.AbstractChoiceHandler.createUtilityExpressionCalculator(AbstractChoiceHandler.java:84) at logSumCalculator.ModeChoiceModel.(ModeChoiceModel.java:41) at logSumCalculator.ModeChoiceTask.run(ModeChoiceTask.java:59)

Is there a problem with how keys are iterated over?

Upvotes: 0

Views: 797

Answers (3)

jtahlborn
jtahlborn

Reputation: 53694

You need to synchronize on the Properties while iterating:

Properties props = System.getProperties();
synchronized(props) {
  // do work here ...
}

Upvotes: 3

OldCurmudgeon
OldCurmudgeon

Reputation: 65889

See the javadoc of HashTable:

if the Hashtable is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a ConcurrentModificationException.

It seems likely that you are calling setProperty on System.getProperties() in another thread.

Upvotes: 2

user3224416
user3224416

Reputation: 530

You cannot modify the keys/contents while iterating or enumerating over the collection.

Create a temp holder for elements to be modified and then use it to make changes.

Upvotes: 0

Related Questions