Monday, January 30, 2012

ObjectOutputStream synchronization

I have recently been working on a client-server multiplayer game. One problem I ran into was one client wouldn't see any changes in the position of another player controlled by a different client. I spent hours trying to find the bug and assumed it was related to concurrency. I made sure to use thread-safe data structures, read articles to make sure the memory that I thought was shared wasn't actually copied where each thread contains its own version of the data, etc.

My problem was not actually in the data, but in how the data was being sent to the clients. I am using an ObjectOutputStream to write data to the clients. The output stream would write the same object often, but I would change values in those objects (usually by a different thread). The output stream tries to speed things up by using the same object I wrote earlier instead of re-writing the object. The stream didn't realize that the data had changed.

The only thing that needed to change was resetting the output stream before writing a batch of objects.

My new code looks something like:

// get request from client
// process data
objectOutputStream.reset();
while(moreData) {
   objectOutputStream.writeObject(dataObject);
}

Hopefully this will help others from the hours of debugging that I went through. Now I need to go clean up my code. Its littered with print statements, commented out blocks of code, and a number of variables are now declared volatile unnecessarily.