Java ConcurrentModificationException由于未同步的同步方法而导致

Java ConcurrentModificationException由于未同步的同步方法而导致,java,multithreading,synchronization,sync,Java,Multithreading,Synchronization,Sync,我有一堆从基类启动的可运行对象。这些对象在随机时间遍历和删除共享ArrayList中的项。我已经同步了这两种方法,但得到了一个ConcurrentModicationException。我相信这是因为。是这样吗?如果是,我应该在哪个类上获得锁 环境等级: class Environment{ ArrayList<Critter> critter_array = new ArrayList<Critter>(); ArrayList<Food&g

我有一堆从基类启动的可运行对象。这些对象在随机时间遍历和删除共享ArrayList中的项。我已经同步了这两种方法,但得到了一个
ConcurrentModicationException
。我相信这是因为。是这样吗?如果是,我应该在哪个类上获得锁

环境等级:

class Environment{

     ArrayList<Critter> critter_array = new ArrayList<Critter>();
     ArrayList<Food> food_array = new ArrayList<Food>();

     Environment(){
         Executor ex = Executors.newCachedThreadPool(); 
         Critter A = new Critter();
         Critter B = new Critter();
         critter_array.add(A);
         critter_array.add(B);
         ex.execute(A); 
         ex.execute(B);
     }

     public synchronized void destroyFood(Food item){
         Iterator<Food> iter = food_array.iterator();
         while(iter.hasNext()){
             Food temp = iter.next();
             food_array.remove(temp);
             break;
         }      
     }

}
CriterUtilities类:

class CritterUtilities{

    public static synchronized iteratorMethod(Critter self, Environment envi){
         Iterator<OtherObject> iter = envi.getFood().listIterator();
         while(iter.hasNext()){
             Food temp = iter.next();   /////////Problem is here
             //other stuff that's not related to the prob
        }
    }

}

此错误不一定会阻止多线程处理,而是因为您在使用迭代器时正在从列表中删除项:

 public synchronized void destroyFood(Food item){
     Iterator<Food> iter = food_array.iterator();
     while(iter.hasNext()){
         Food temp = iter.next();
         food_array.remove(temp); // <-- this is the problem
         break;
     }      
 }


另一方面,您的同步是错误的。每个
synchronized
方法都在不同的对象上同步。要让它们在同一个对象上同步,最简单的方法可能是让它们在列表本身上同步。

除了DaoWen发现的错误删除之外,同步也是错误的
iteratorMethod()
destroyFood()
不使用同一对象进行同步。目前,它们使用各自的对象进行同步。应该是这样的:

 public void destroyFood(Food item) {
     synchronized (food_array) {
         // ... proceed with the removal
     }
 }

publicstaticiteratormethod(生物自身、环境环境){
List=envi.getFood();
已同步(列表){
//iteratorMethod的其余部分应该放在这里
}
}
(我假设getFood()返回食物数组,因此对象是相同的)


同样的修正也适用于修改或迭代食物列表的任何其他方法。

是的,它们在不同的东西上同步。销毁方法中的“食物列表”是什么?@ChristianSchneider my bad,编辑concurrentModificationException如果你在循环过程中移除东西,通常会出现这种情况。你确定没有在循环中的某个地方调用xxx.remove()吗?问题,因为我以前从未使用过这个类:这会从原始列表(在本例中为
food\u array
)中删除元素吗?@Deactivator2-更新了我的答案。文档中说它将从列表中删除它,而不仅仅是从迭代器中删除。您不需要
ListIterator
。与常规的
迭代器相比,它增加的唯一一点是,您可以在两个方向上进行迭代<代码>删除
对两者都是一样的。@zapl-你说得对。我甚至仔细检查了一下,不知怎么还是没看到。。。我更新了我的答案。
 public synchronized void destroyFood(Food item){
     Iterator<Food> iter = food_array.iterator();
     while(iter.hasNext()){
         Food temp = iter.next();
         food_array.remove(temp); // <-- this is the problem
         break;
     }      
 }
 public synchronized void destroyFood(Food item){
     Iterator<Food> iter = food_array.iterator();
     while(iter.hasNext()){
         iter.remove(); // <-- this is how you remove elements while iterating
         break;
     }      
 }
 public void destroyFood(Food item) {
     synchronized (food_array) {
         // ... proceed with the removal
     }
 }
public static iteratorMethod(Critter self, Environment envi){
    List<OtherObject> list = envi.getFood();
    synchronized (list) {
        // the rest of iteratorMethod should go here
    }
}