Thread Safety Dance
Another blast from the past.
If you’re working with Servlets or in a Threaded environment, you need to be thinking about thread safety.
Thread Bare
Java has built in support for multiple threads in all its objects. The way it handles this, is each thread can get a handle on the object and run its methods at the same time which, for something like a servlet, cuts down on the amount of memory needed to load the servlets and the amount of time needed to instantiate multiple objects. This can be a huge improvement in performance for web-based applications.
But what does it mean when objects are used by multiple threads? To answer that, we’ll need to look at variable scoping.
Scoping It Out
Let’s look at a simple example:
class Example {
int a;
public int scopedMethod(int b) {
int c = 10;
a = c + b;
return a;
}
}
When an object is created from this class, that object will have two things in scope; the variable a
and the method scopedMethod
. The variables b
and c
don’t even exist until the method scopedMethod
is called.
What does this mean for threads? If multiple threads use the same object, like for JEE Servlets, they will share things that are in the object scope when it’s created. So all threads will share the variable a
and the method scopedMethod
. Sharing methods is okay since every thread will create it’s own execution stack when it calls the method. That means every thread will own the variables b
and c
when scopedMethod
gets called.
But what about variable a
?
Crossing the Streams
Imagine two threads executing at nearly the same exact moment; we’ll call them thread 1 and thread 2. Thread 1 calls scopedMethod
and passes in 50
to b
. Thread 2 then calls scopedMethod
at the same time, passing 700
to b
. Since both threads have their own variable b
, this doesn’t cause any problems. Now, thread 1 creates variable c
and calls a = c + b;
. Then, thread 2 will create it’s own variable c
and call a = c + b;
Now a
equals 710 in both threads. Since the threads share the variable a
, both threads will now return 710, which is obviously wrong for thread 1. Imagine if this was a servlet and a
contained sensitive customer data for two different customers. Now, both customers would see the data for the customer in thread 2!
S - A - F - E - T - Y, Thread Safety
Don’t use instance variables in multithreaded objects.
In a servlet environment, if you have data you need to store “globally” for this thread or user request, use the session or request objects. There shouldn’t be a need for changeable instance variables. If you have constants in the class that don’t change, it should be okay to make those instance variables, but declare them as static and final to make sure that they never change and all threads get the same value from them.
And remember, you won’t see threading problems in testing. When your application is being tested, it’s usually by one person on the system by themselves and they will never hit a threading issue here. You will only see threading issues in real world situations, when there are so many people hitting the application that your object will be executed twice at the exact same time. You can’t rely on testing to find these problems for you, you’ll need to do it as you develop your application.
For more info, see http://www.javaworld.com/javaworld/jw-07-2004/jw-0712-threadsafe.html