Tuesday, 27 August 2013

Singleton Synchronization in Java

Singleton Synchronization in Java

I am making an online game and have a few singletons that represent the
locations in the world which are accessible to all users. Right now I have
the following Location Superclass:
public abstract class Location {
protected List<CharacterHandler> people; // list of people in current
location
protected Map<String, Command> locationCommands;
protected Map<String, Fight> fightsInProgress;
public Location() {
this.people = Collections.synchronizedList(new
ArrayList<CharacterHandler>());
}
public void addCharacter(CharacterHandler character) {
...
synchronized(people) {
for (CharacterHandler hero : people) {
hero.onReceive(enterMessage);
peopleNames.add(hero.getName());
}
...
...
character.onReceive(message);
}
}
public void removeCharacter(CharacterHandler character) {
...
synchronized(people) {
people.remove(character);
distributeMessageAll(lieveMessage);
}
}
protected void distributeMessageAll(GameMessage message) {
synchronized(people) {
for (CharacterHandler character : people) {
character.onReceive(message);
}
}
}
}
The problem is that this is the method in CharacterHandler object that is
used to send messages:
public synchronized void sendResponse(SystemNotification message) {
if (stream != null) {
JAXB.marshal(message, stream);
if (message.getCode() == 0) {
finalizeGame();
try {
this.stream.close();
this.stream = null;
} catch (IOException e) {
Logger.getLogger("server").log(Level.SEVERE,
"Could not close the output stream of the
connection!", e);
}
}
}
}
finalize() method removes the character from the location (by using
removeCharacter()-method of the singleton location) when the appropriate
code is received. But then sendResponse() is a synchronized mthod of
CHaracterHandler. If another thread is sending message to all players in
the location, it will get stuck upon this particular character who holds
the lock for its send() method while the character is trying to remove
itself from location, but cant aquire lock for the people-collection of
the location. How can I avoid such a deadlock?

No comments:

Post a Comment