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)
excalibur
  • 924
  • 2
  • 11
  • 26
  • 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. – Cruncher Oct 03 '13 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) – Jason Nichols Oct 03 '13 at 17:00
  • @JasonNichols Fair enough, but at the least, not in this case – Cruncher Oct 03 '13 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). – jtahlborn Oct 03 '13 at 17:01
  • show the full exception stack trace. – jtahlborn Oct 03 '13 at 17:01
  • You are showing FooManager but what about FooHandler.addFoo(this); ? ArrayList is not thread safe, that means that you can call .add somewhere else away in a non sync block and it may steal the lock. – porfiriopartida Oct 03 '13 at 17:01
  • See here: http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedList%28java.util.List%29 Maybe this helps you – angel_navarro Oct 03 '13 at 17:02
  • You can try using: `Collection c = Collections.synchronizedCollection(myCollection);` – porfiriopartida Oct 03 '13 at 17:03
  • Similar problem here but did not find why : http://stackoverflow.com/questions/19138161/how-can-a-synchronized-iteration-on-a-set-fail-with-a-concurrentmodificationexce/19138220#19138220 – Arnaud Denoyelle Oct 03 '13 at 17:11
  • the way you done it I would have made the sync object `static final`. But see also this thread : http://stackoverflow.com/questions/1431681/correct-way-to-synchronize-arraylist-in-java – nha Oct 03 '13 at 17:15
  • As `m_globalFoosis` is static with default visibility, are you sure you never call `FooManager.m_globalFoos.add/remove()` directly? I suggest you to make it private. – Arnaud Denoyelle Oct 03 '13 at 17:17
  • @Cruncher yes multiple threads are involved - I mentioned that above. ABC2, ABC3 etc are used in thread funcs which cause their static (which calls addFoo) to get executed in that particular thread. – excalibur Oct 03 '13 at 18:47
  • @Arnaud - no issue with accessing m_globalFoos other than as shown – excalibur Oct 03 '13 at 18:51
  • are you calling synchronized functions from the main thread as well? Or does everythin happen in the sub threads? – prom85 Oct 03 '13 at 20:08
  • addFoo() and showFoos() are called from main thread. addFoo() is also called from other threads. – excalibur Oct 03 '13 at 20:12
  • Possible duplicate of [ConcurrentModificationException despite using synchronized](http://stackoverflow.com/questions/1655362/concurrentmodificationexception-despite-using-synchronized) – Raedwald Jan 22 '16 at 15:59

3 Answers3

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.

Ashley
  • 629
  • 3
  • 6
  • 16
  • 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. – excalibur Oct 03 '13 at 20:11
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).

jtahlborn
  • 52,909
  • 5
  • 76
  • 118
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.

barmatat
  • 291
  • 2
  • 10
  • sorry was a typo...it's FooManager, not FooHandler..its part of a larger codebase, so i cut out whats reqd – excalibur Oct 03 '13 at 20:07