java - 解决 ConcurrentModificationException

标签 java thread-safety concurrentmodification

我正在编写一个小游戏,屏幕上有许多圆圈在移动。
我正在两个线程中管理圈子,如下所示:

public void run() {
    int stepCount = 0;
    int dx;
    int dy;
    while (m_threadTrap){
        dx = 0;
        dy = 0;

        synchronized (m_circles) {
            for (Iterator<Circle> it = m_circles.iterator(); it.hasNext();){
                Circle c = it.next(); //Exception thrown here.
                if (c.getDirX() != 0)
                    if (stepCount % c.getDirX() == 0){
                        dx = 1;
                    }
                if (c.getDirY() != 0)
                    if (stepCount % c.getDirY() == 0){
                        dy = 1;                 
                    }

                c.move(dx, dy); 
            }
        }
        if (stepCount == 150000){
            stepCount = 0;
        }
        stepCount++;
    }
}

圆数组列表中的 m_circles。

以及以下主题:

public void run() {
    while (m_threadTrap){
        int topPosition;
        int bottomPosition;
        int leftPosition;
        int rightPosition;
        ArrayList<Circle> removedCircles = new ArrayList<Circle>();
        synchronized (m_circles.getCircles()) {
            for (Iterator<Circle> it = m_circles.getCircles().iterator(); it.hasNext();){
                Circle c = it.next();

                // Some calculation to evaluate which circles should be removed
                    removedCircles.add(c);
                }
            }
        }
        try{
            Thread.sleep(25);
        }
        catch (Exception e) { }

        m_circles.getCircles().removeAll(removedCircles);

        if (m_circles.getCircles().size() < 30)
            m_circles.addNewCircle();

        repaint(); 
    }
}

我的问题是我在该行收到 ConcurrentModificationException

Circle c = it.next();

在第一个线程中。起初,我尝试使用 foreach 循环遍历 ArrayList,这给了我同样的异常。
在对这个异常进行了一些研究之后,我看到了两种解决方案:
1. 将访问集合的部分放在同步块(synchronized block)中。
2.使用集合的Iterator对象。
他们都没有为我解决这个问题。

最佳答案

要使 synchronized() {} block 有效,对 protected 对象的所有访问必须包装在同步块(synchronized block)中。您可能忘记包装一些访问权限。

另一个“问题”是 ConcurrentModificationException 也可能意味着它是在同一个线程中同时修改的。例如,如果在遍历集合时从集合中删除一个元素,则可能会出现此异常。 (作为异常(exception),您可以通过迭代器本身安全地删除元素)

关于java - 解决 ConcurrentModificationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9224821/

相关文章:

java - java HashMap 的快速失败行为

java - JSP 究竟在哪里运行?在客户端还是服务器端?

java - 有没有办法在不重新绑定(bind)的情况下更新 RecyclerView 中的某些项目?

java - 如何将 Ruby on Rails 编写的网站与 Android 应用程序连接到使用 Postgresql 的 Heroku 上托管的相同数据库

java - 在 client.execute(httpGet) 的 doInBackground() 行上发生崩溃。为什么?

java - 我有 2 个并发数据结构,我想自动更新它们

java - 以编程方式设置 StyleClassedTextArea 的文本

c# - 以线程安全的方式设置 ToolStripLabel

multithreading - 这个 CMPXCHG16B 指令的仿真有什么问题?

java - SortedSet::removeAll( headSet ) 失败,但从 headSet 派生另一个集合成功。为什么?