繁体   English   中英

多线程 Java 应用程序中的 ConcurrentModificationException

[英]ConcurrentModificationException in multithreaded Java application

我有以下问题:我们在做多线程游戏,有一个Server扩展了Thread并且是游戏的主机,还有一个GameUpdater也扩展了Thread并且是游戏引擎的原型。 问题是GameUpdater向游戏添加和删除了一些 object,而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发送不存在的对象。 问题的解决方法找到了:制作小行星的副本,然后发送给Client ,但问题是它需要大量的memory。 任何其他解决方案都值得赞赏(例如使两个不同的线程一起工作)。

如果列表中的元素更新(添加/删除)与迭代相比不那么频繁,我建议考虑 CopyOnWriteArrayList。 除非涉及频繁写入,否则对于安全迭代是有效的。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM