Thursday, March 19, 2009

Concurrency issues with Java

What I really want to discuss is a recent experience I had with a client and the first task I had on site with them.

client: “Hey we have some unsafe thread code, we need you guys to fix it.”
me: “Okay, but is there a specific example of what makes you feel there’s unsafe thread code?”
client: “Yeah, everyone that uses the system says, that every once in awhile they’ll try to go view a particular piece of content, and they get a completely different unrelated piece of content.”

Ahhhhhh, sounds like a concurrency issues! Here’s a little history about this application and the singleton design pattern and how it was misused, and a couple solutions. This particular application was written with the Spring Framework and a very common thing to do [okay, almost always] is create singletons. Huh, what’s a singleton? A singleton is a common design pattern. It refers to a class which is not meant to be freely instantiated, but have only one instance. If you’ve ever used Servlets then you know all you need to know, unless you don’t understand the stateless programming paradigm, ahhhhh.

Let’s talk about the definition I gave you above for the singleton pattern and discuss stateless programming for a minute. The singleton pattern says you only have one instance. This simply means that for every user/thread accessing the singleton will get the same one that every other user/thread got. Okay, got it, cool let’s talk about how this can get you in trouble.

1. Question, what happens if you have a singleton class with a class level attribute and a user/thread alters the state of that attribute via a public method? Answer, the attribute is changed for every user/thread that is accessing the singleton instance.

2. Question, does the JVM wait for the completion of the current executing method call before executing the same method call from another thread? Answer, well okay it depends, we can use the synchronized keyword to force the JVM to do this, but I’ll answer it like this NO, it doesn’t wait, and depending on how the virtual machine queues the thread for execution doesn’t even ensure a thread that started before yours will go first.

3. Question, who knows what else we can call the condition created by question one and question two? Answer, a race condition, nice one!

Okay, but what does this mean. It means we create scenarios like this in systems that have concurrent access:

client: “Yeah, everyone that uses the system says, that every once in awhile they’ll try to go view a particular piece of content, and they get a completely different unrelated piece of content.”

Guess what 9 times out of 10 a developer guilty of writing race condition code would never see the problem. Why? They generally only access the system with a single thread of execution [ie. they’re the only ones using the system]. Often times this passes right by a QA team too, why, because they aren’t creating concurrency on the system either.

So how do we fix it? The thing is we need to put all our code in a method block or we need to synchronize the method call. I’ll recommend the… put all your code in the method block, the synchronized keyword on a method in Java means that we block until that method has completed, this means Java will queue all the threads wanting access to the method until it’s complete. Little side note for you; singleton class level attributes are fine if you want the change to be acknowledged by every user/thread accessing the singleton class, but just make sure that’s the case and it’s not dynamic data; the dynamic data needs to live inside a method block.

Simple Illustration:

Here’s what I’m trying to illustrate let’s say user 1 accesses the loadMyUrl(int id) method and pass an id of 2 in, notice we just reassigned the class url. If user 2 accesses the loadMyUrl(int id) method and pass an id of 3 in, the JVM will not guarantee that user 1 will get the url he expected same goes for user 2. If you do I’d call it the luck of the Irish and don’t bet on it.

class BadContentGetter{

string url;

public string loadMyUrl(int id){
url = getMyUrl(id);

return url;
}
}

So how do we fix it and how did I fix it in the real scenario mentioned above? It’ really quite simple, remove the class level attribute and put the attribute in the method. You are now stateless.

class GoodContentGetter{

public string loadMyUrl(int id){
string url = getMyUrl(id);

return url;
}
}

Here’s how I like to think about the singleton pattern, it will give me a new instance of the code executing inside a method and give me the same class instance always, don’t new it up please. If you really think about this pattern it’s pretty amazing. Think about this for a second if you use a stateful paradigm you have to have something that ensures that everyone/thread gets their own copy, which means some kind of newing up process or some kind of pool access and pool return over head. Using stateless programming and the singleton pattern you don’t need this, and in my opinion is solid as a ROCK ;)!

Cheers till next time.

No comments:

Post a Comment