【问题标题】:ConcurrentModificationException in multithreaded Java application多线程 Java 应用程序中的 ConcurrentModificationException
【发布时间】:2020-02-21 18:19:38
【问题描述】:

我有以下问题:我们正在做多线程游戏,有一个 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 不存在的对象。问题的解决方法找到了:制作小行星的副本,然后发送到Client,但问题是它占用大量内存。任何其他解决方案都值得赞赏(例如让两个不同的线程一起工作)。

【问题讨论】:

  • 此代码没有任何可能导致异常的内容。如果迭代和添加/删除操作同时发生,则会发生异常。请检查可能发生上述操作的代码n如果可能的话将代码添加到问题中
  • 这就是为什么我写的问题是两个单独的线程修改了这个 ArrayList 并导致了这个异常。
  • 如果您知道哪个方法正在修改列表,只需使用 synchronized 关键字使它们同步即可。这取决于您希望在哪个级别阻塞线程,即在方法级别或某个代码块
  • 使用 Vector(为了同步小行星列表)而不是 ArrayList
  • 你是什么意思,你发送更新的小行星?你正在遍历所有的小行星并发送它们。

标签: java multithreading arraylist server concurrentmodification


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    相关资源
    最近更新 更多