1

Similar issue has been posted before but this case is different - there is static usage which may be the complicating it. Just want to see if anyone has ideas on how to handle this. I get the ConcurrentModificationException even though I am using synchronzed on the list around both blocks that modify it.

public class Foo {
   public void register() {
       FooManager.addFoo(this);
   }
}

public class ABC1 {
   static Foo myfoo;
   static {
     myfoo = new Foo();
     myfoo.register();
   }
}

(I have mutliple similar classes ABC2, ABC3)

public class FooManager {
   static ArrayList<Foo> m_globalFoos;
   static ABC1 m_abc;
   static {
     m_globalFoos = new ArrayList<Foo>();
     m_abc = new ABC1();
   }


   public static void addFoo(Foo foo) {
     synchronized(m_globalFoos) { // SYNC
         m_globalFoos.add(foo);
      }
   }

    public static void showFoos() {
        synchronized(m_globalFoos) { //SYNC
            for (Foo foo : m_globalFoos) {
                     foo.print();
            }
    }
}

I declare ABC1, ABC2, ABC3 etc in more than 1 thread func. In my main program, first line

main() {
    FooManager.showFoos();

Exception details:

Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
        at java.util.AbstractList$Itr.next(AbstractList.java:343)
        at com.mytest.FooManager.showFoos(FooManager.java:78)
        at com.mytest.FooTest.main(FooTest.java:109)
16
  • Is there only 1 thread here? You can't get concurrentmodification with only a single thread. To see how this can actually happen I need to see when and how you make threads. Commented Oct 3, 2013 at 16:58
  • 4
    Sure you can, try looping through a Set and removing an item from within the loop (without using the proper iterator.remove method) Commented Oct 3, 2013 at 17:00
  • @JasonNichols Fair enough, but at the least, not in this case Commented Oct 3, 2013 at 17:00
  • @Cruncher - actually, you can get a ConcurrentModificationException with one thread. in fact, that's the most likely scenario (and most common bug). Commented Oct 3, 2013 at 17:01
  • show the full exception stack trace. Commented Oct 3, 2013 at 17:01

3 Answers 3

3

Actually, your intrinsic lock is on the ArrayList that you are iterating. Looks like either the FooHandler OR the print() function has a reference back to your ArrayList which is trying to add/remove content to it. According to JAVADOC, this exception can happen because of either the same thread or a different thread, but not always a different thread. So, if you have some kind of operation that is trying to modify your Arraylist, then this error can occur.

try to use fail-fast iterators for avoiding such errors.

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

1 Comment

what i show here is the only 2 places where the Arraylist is used. there is no other modification happening. And I have the synchonized around both blocks regardless.
0

You don't include a lot of code, but my guess is that foo.print is doing something which is ultimately invoking a call to addFoo (pretty much guarantee that the stacktrace for the CME has both showFoos and addFoo in it). 99 times out of 100, ConcurrentModificationException is caused by a single thread, not multiple threads (despite the confusing name).

(and yes, this "bug" is the same as all the other SO posts about CME).

6 Comments

We don't have this code either: FooHandler.addFoo(this); but FooManager.addFoo instead.
@porfiriopartida - FooHandler and FooManager are probably the same class, just mistyped.
yes - fixed the typo. print dosent do anything - just prints out - and no it dosent call addFoo.
@excalibur - is there any access to m_globalFoos other than the 2 methods shown?
@excalibur - do either of these methods re-assign m_globalFoos?
|
0

You probably work with other class, in your main() you use FooHandler, but you don't provide its code in your question... If it is not, please post stack trace for the exception here.

1 Comment

sorry was a typo...it's FooManager, not FooHandler..its part of a larger codebase, so i cut out whats reqd

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.