I have the following problem: We are doing multithreaded game and there is a Server
which extends Thread
and is the host of the game, as well there is a GameUpdater
which also extends Thread
and is a prototype of game engine. The problem is that GameUpdater
adds and removes some object to the game, while Server
sends to Client
all updates (example given below):
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();
}
}
The following error always occurs:
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1042)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:996)
I think that the problem is that GameUpdater
removes and adds objects, and then Server
tries to send to Client
non-existing objects. The solution to the problem was found: making copy of asteroids and then send it to Client
, but the problem is that it takes a lot of memory. Any other solutions are appreciated (for example make two different threads working together).
If element updates in list (add/remove) is less frequent compare to Iteration, I would suggest to consider CopyOnWriteArrayList. Unless frequent write is involved, It is efficient for safe iteration.
Otherwise Collections.SynchronizedList could be used with synchronized block over iteration of the list. This will cause the other thread to wait till iteration completes