【发布时间】:2011-05-05 09:49:03
【问题描述】:
我搜索了 StackOverflow 并且有很多 ConcurrentModificationException 问题。读完之后,我还是一头雾水。我得到了很多这样的例外。我正在使用“注册表”设置来跟踪对象:
public class Registry {
public static ArrayList<Messages> messages = new ArrayList<Messages>();
public static ArrayList<Effect> effects = new ArrayList<Effect>();
public static ArrayList<Projectile> proj = new ArrayList<Projectile>();
/** Clears all arrays */
public static void recycle(){
messages.clear();
effects.clear();
proj.clear();
}
}
我通过像这样访问 ArrayLists 向这些列表添加和删除对象:Registry.effects.add(obj) 和 Registry.effects.remove(obj)
我设法通过使用重试循环解决了一些错误:
//somewhere in my game..
boolean retry = true;
while (retry){
try {
removeEffectsWithSource("CHARGE");
retry = false;
}
catch (ConcurrentModificationException c){}
}
private void removeEffectsWithSource(String src) throws ConcurrentModificationException {
ListIterator<Effect> it = Registry.effects.listIterator();
while ( it.hasNext() ){
Effect f = it.next();
if ( f.Source.equals(src) ) {
f.unapplyEffects();
Registry.effects.remove(f);
}
}
}
但在其他情况下,这是不切实际的。我在drawProjectiles() 方法中不断收到 ConcurrentModificationExceptions,即使它没有修改任何内容。我想罪魁祸首是如果我触摸了屏幕,它会创建一个新的 Projectile 对象并将其添加到 Registry.proj,而 draw 方法仍在迭代。
我不能很好地用draw方法做一个重试循环,否则它会重新绘制一些对象。所以现在我不得不寻找一个新的解决方案。有没有更稳定的方法来完成我正在做的事情?
哦,我的问题的第 2 部分:许多人建议使用 ListIterators(正如我一直在使用的那样),但我不明白.. 如果我调用 ListIterator.remove(),它是否会从它正在迭代的 ArrayList 中删除该对象,或者只是从迭代器本身中删除它?
【问题讨论】:
标签: iterator arraylist concurrentmodification concurrent-collections