这段代码抛出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
答案 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,这实际上是不可能的,但是,根据你的计算机数学,也许它可能发生在你的虚拟世界......: - )