【发布时间】: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