多线程 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 可以在列表的迭代中与同步块一起使用。这将导致另一个线程等待迭代完成
我有以下问题:我们正在做多线程游戏,有一个 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 可以在列表的迭代中与同步块一起使用。这将导致另一个线程等待迭代完成