java ConcurrentModificationException甚至是synchronized

时间:2013-10-03 16:48:59

标签: java synchronized

之前已经发布了类似的问题,但这种情况有所不同 - 有静态使用可能使其复杂化。 只是想看看是否有人有关于如何处理这个问题的想法。 我得到了ConcurrentModificationException,即使我在两个修改它的块的列表上使用同步。

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

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

(我有类似的类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();
            }
    }
}

我宣布 ABC1,ABC2,ABC3等超过1个线程函数。 在我的主程序中,第一行

main() {
    FooManager.showFoos();

异常详情:

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)

3 个答案:

答案 0 :(得分:3)

实际上,您的内部锁定在您正在迭代的ArrayList上。看起来像FooHandler或print()函数有一个引用回到您正在尝试添加/删除内容的ArrayList。根据JAVADOC,这个异常可能由于相同的线程或不同的线程而发生,但并不总是不同的线程。因此,如果您正在尝试修改Arraylist的某种操作,则可能会发生此错误。

尝试使用fail-fast迭代器来避免此类错误。

答案 1 :(得分:0)

你没有包含很多代码,但我的猜测是foo.print正在做一些最终调用addFoo的东西(几乎可以保证CME的堆栈跟踪都有其中showFoosaddFoo)。 99次中的100次,ConcurrentModificationException是由单个线程引起的,而不是多个线程(尽管名称令人困惑)。

(是的,这个“bug”与关于CME的所有其他SO帖子相同)。

答案 2 :(得分:0)

您可能使用其他类,在您的main()中使用FooHandler,但是您没有在您的问题中提供其代码...如果不是,请在此处发布异常的堆栈跟踪。