0

I'm trying to iterate through a Integer ArrayList and getting the value at each element, but I'm getting an error at the int value = ....

Not sure whats happening. Please advise.

Iterator<Integer> listItr = executeList.iterator(); // iterator for the execute list 
    while (listItr.hasNext()) { // iterate through list and do work!
        int robIndex = listItr.next();
        int timer = fakeRob.exeCountDown(robIndex); // decrement first then return timer
        if (timer == 0) {// check if instr finished execution
            System.out.println("timer expired. fire");
            executeList.remove(executeList.indexOf(robIndex)); // 1. remove instr from exeList
            transitState(robIndex, EX, WB); // 2. transit from EX state to WB state
            int tag = fakeRob.getTag(robIndex); // get producer tag
            regFile.setRdy(tag); // 3a. set register file ready flag for this tag
            fakeRob.wakeUp(tag); // 3b. wake up instructions with this tag
        }
    }

Error:

java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at sim.execute(sim.java:180)
at sim.<init>(sim.java:71)
at sim.main(sim.java:270

Thanks,

Hank

7
  • 4
    Are you modifying the list as you're iterating over it? Is another thread accessing the same list at the same time? Commented May 5, 2012 at 23:17
  • From a quick glance, it seems this code snippet with an iterator shouldnt be throwing that exception. Are you sure you pasted the correct code? Commented May 5, 2012 at 23:18
  • I recently participated in a similar discussion in stackoverflow.com/a/10432084/697630, perhaps it helps clarify why this is happening in your code. Commented May 5, 2012 at 23:24
  • Could you please paste more code perhaps in pastebin so that we can see what's going on? The code as is shouldn't throw the ConcurrentModificationException. Commented May 5, 2012 at 23:26
  • Add the code for do some stuff with value at each iteration, are you removing the item from list? are you adding new items to the list? Commented May 5, 2012 at 23:47

2 Answers 2

1

Perhaps if you put what it is you're doing inside the loop it would help. If you're trying to remove an element from the list, you need to call listItr.remove() to do it. In general, you should not be calling any functions in the loop which modify the list (ie. add(), set(), etc...).

The following code would trigger this

Iterator<Integer> it = executeList.iterator();
while (it.hasNext()) {
  Integer i = it.next();
  executeList.remove(i);
}

The proper way to do it would be:

Iterator<Integer> it = executeList.iterator();
while (it.hasNext()) {
  Integer i = it.next();
  it.remove();
}

Also other threads (as mentioned above) could be the issue. Remember, iterators are backed by the list itself in all the java supplied collections. So if another thread modifies the list while you'e iterating, you'll run into this.

Sign up to request clarification or add additional context in comments.

4 Comments

This is a single threaded program. I will go ahead and give your solution a try and see what happens. I'm curious though, what is going behind the scene for executeList.remove(i) vs it.remove(i)?
The Iterator knows all about itself, so it isn't "surprised" when it deletes an entry. Though it obviously knows something about the list, when the list removes a value, the iterator detects that the list has changed (via a counter that gets incremented as things are changed) but doesn't know how to correct for it, so it throws the ConcurrentModificationException.
I see. In the "proper way" posted by Matt. It will always begin removing from the first element in the list right?
Yes. Javadocs for List.remove() say "Removes the first occurrence..."
1

If the local variable value is the thing that you "do some stuff with", and you are not modifying the list, then some outside thread is modifying the list while you are in there.

Otherwise, see the link provided by @edalorozo for some ideas

EDIT ADDED

I never use the iterator.remove() idiom, because I never got all that familiar with the iterator idiom. And always mixed it up with the short lived and poorly implemented Enumerator stuff. Before the enhanced for loop, I typically looped using the very old fashioned for (int i-0; i<foo.length; i++) style. And not all Iterators support remove(), so what's the point?

Therefore, I got "used to" the "collect everything and delete it afterwards" style, even when I now use the enhanced for loop. In your code, that would be:

ArrayList <Integer> toBeRemoved = new ArrayList <Integer>();
for (Integer robIndex : executeList) {
   // note, I distrust auto-unboxing, (see all the Java Puzzlers books!)
   // so I'd probably add an explicit unbox here
   int robIndexi = robIndex.intValue();

   int timer = fakeRob.exeCountDown(robIndexi); // decrement first then return timer
   if (timer == 0) {// check if instr finished execution
      toBeRemoved.add(robIndex);
      // all that other stuff here...
   }
}

// remove everything now
executeList.removeAll(toBeRemoved);

2 Comments

Thanks for your comment. The list is actually being modified. I've revised my post to add the whole method if you could take another look and let me know what you think. Thanks
See comment below @Matt answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.