java - 为什么我会得到带有迭代器的 java.util.ConcurrentModificationException?

标签 java multithreading concurrency iterator

我正在尝试编写一个游戏,所以我在每一帧调用 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/

相关文章:

java - 如何从 Tomcat Java 应用程序捕获 SOAP 消息到外部服务器?

java - 根据特定字符串位置将字符串附加到文件

java - java Visual VM如何连接到eclipse java任务

c++ - 在 "wrapper"类中使用原子类型

ios - 虽然项目正在保存在核心数据中,但在重新启动之前无法查看它们

sql - Postgres Serialized 似乎不像描述的那样工作

java - Android Studio,调用不同文件中的不同类

c - pthread_cancel() 在传入类型转换的 void 指针时不起作用

linux - 'atomicity' 在编程中的确切定义是什么?

multithreading - 你能为线程指定一个非静态的生命周期吗?