ConcurrentModificationException的

时间:2014-06-30 19:25:18

标签: java android exception

这段代码抛出ConcurentModificationException。这是在我的功能称为更新巫婆是Android游戏的一部分,它被称为60次/分钟(我认为这是问题,但IDK):

List<Bullet> blts = robot.getBullets();
        if (blts.size() > 0 && enemys.size() > 0) {
            Iterator<Bullet> it_b = blts.iterator();
            Iterator<Enemy> it_e = enemys.iterator();
            while (it_e.hasNext()) {
                Enemy e = it_e.next();
                it: while (it_b.hasNext()) {
                    Bullet b = it_b.next();
                    if (b.getRect().intersect(e.getRect())) {
                        e.degreesHealth(20);
                        it_b.remove();
                        if (e.getHealth() <= 0) {
                            it_e.remove();
                            break it;
                        }
                    }
                }
            }
        }

如果是重要的,这是全班:http://pastebin.com/R4rX7DBY

3 个答案:

答案 0 :(得分:4)

你遍历你的enemys.iterator()it_e,当你这样做的时候,你可以用it_e.remove();删除一个元素,可能不止一次。

Iterator的javadocs说你每remove()只能调用一次next(),但是因为你在内循环(it_e.remove())中调用了while (it_b.hasNext()),你很可能从父循环(it_e.remove())每it_e.next()次多次调用while (it_e.hasNext())

http://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html#remove()

答案 1 :(得分:1)

在调用程序主线程上的其他方法之前启动了MyThread线程。因此,当主线程填充您的列表时,MyThread线程正在尝试访问和删除列表中的项目...您不能同时修改这样的列表,我建议,加载所有内容,然后启动MyThread。

您可以在代码中的任何位置初始化线程MyThread,但请确保加载所有列表,然后启动它。否则,您将尝试同时删除和添加项目,但这不起作用。

Thread mythread = new MyThread();可以在您开始通话之前放在任何地方

在所有将项目加载到列表中的方法之后,必须放置起始呼叫mythread.start

希望这有帮助!

答案 2 :(得分:0)

所有迭代器和ConcurrentModification麻烦的常见解决方法是收集要删除到列表中的所有敌人和子弹,然后一次性将其全部删除。它也是,IMO,使代码更简单,更容易阅读。

List<Enemy> deadEnemies = new ArrayList<Enemy>();
List<Bullet> usedBullets = new ArrayList<Bullet>();
for (Enemy e : enemys) {
   for (Bullet b : bullets) {
      if they intersect {
         if enemy is out of health then 
            deadEnemies.add(e);
         usedBullets.add(b);
      }
   }
}

// iteration is now done, so much lower chance of a ConcurentModificationException
    enemies.removeAll(deadEnemies);
    bullets.removeAll(usedBullets);

一个小的区别是子弹可以杀死多个敌人,如果允许敌人重叠,则敌人可以使用多个子弹。因为子弹和人是Fermions,这实际上是不可能的,但是,根据你的计算机数学,也许它可能发生在你的虚拟世界......: - )