我正在尝试编写一个游戏,所以我在每一帧调用 doDraw() 方法,我在其中使用迭代器循环遍历所有游戏对象并将它们全部打印在屏幕上:
Iterator<GameObject> itr = mObjList.iterator();
while (itr.hasNext()) {
GameObject obj = itr.next(); // this line gives me the error
...
// print object
}
将项目添加到列表的唯一方法是:
public void click(int x, int y) {
// adds new object to the list on a click event
mObjList.add(new GameObject(x, y));
}
大多数情况下它都有效。但有时我会收到此错误:
java.util.ConcurrentModificationException
来自带有“itr.next()”的行。从我用谷歌搜索的内容来看,我认为这是因为 click() 事件有时会在 draw() 完成绘制每个对象之前发生,因此它在迭代器使用它时更改了列表。我想这是哪里出了问题?
但我对线程没有经验。我怎么可能解决这个问题?也许我做错了整件事,我应该使用完全不同的方法在屏幕上打印所有对象?
最佳答案
如果预期的读取和遍历次数大大超过列表的更新次数,请使用 CopyOnWriteArrayList .
否则,在迭代和变异时在列表(或专用互斥对象)上同步
:
private List<GameObject> mObjList = /* whatever */;
private final Object mListMutex = new Object();
// snip...
synchronized (mListMutex) {
for (GameObject obj : mObjList) {
// do your thang
}
}
// snip...
public void click(int x, int y) {
GameObject obj = new GameObject(x, y);
synchronized (mListMutex) {
mObjList.add(obj);
}
}
关于java - 为什么我会得到带有迭代器的 java.util.ConcurrentModificationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8004489/