多线程 Java 应用程序中的 ConcurrentModificationException

ConcurrentModificationException in multithreaded Java application

我有以下问题:我们正在做多线程游戏,有一个 Server 扩展 Thread 并且是游戏的宿主,还有一个 GameUpdater它也扩展了 Thread 并且是游戏引擎的原型。问题是 GameUpdater 在游戏中添加和删除了一些对象,而 Server 发送给 Client 所有更新(下面给出的示例):

private void sendUpdatedAsteroids() {
        Collection<Asteroid> asteroids = this.game.getAsteroids();
        StringBuilder existentAsteroids = new StringBuilder();
        for(Asteroid asteroid : asteroids) {
            if (!asteroid.isDestroyed()) {
                existentAsteroids.append(asteroid.getUniqueID());
                existentAsteroids.append("@");

                Message message = new Message();
                message.encryptObject(asteroid);
                try {
                    this.sendMessage(message);
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
            }
        }


        Message message = new Message(MessageType.GENERAL, existentAsteroids.toString());
        try {
            sendMessage(message);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

总是出现以下错误:

    at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1042)
    at java.base/java.util.ArrayList$Itr.next(ArrayList.java:996)

我认为问题在于 GameUpdater 删除和添加对象,然后 Server 尝试发送到 Client 不存在的对象。找到了解决问题的方法:复制asteroids然后发送到Client,但问题是它占用了大量内存。感谢任何其他解决方案(例如让两个不同的线程一起工作)。

如果列表 (add/remove) 中的元素更新与迭代相比不太频繁,我建议考虑 CopyOnWriteArrayList。 除非涉及到频繁写入,否则安全迭代是高效的。

否则 Collections.SynchronizedList 可以在列表的迭代中与同步块一起使用。这将导致另一个线程等待迭代完成