Showing posts with label Singleton. Show all posts
Showing posts with label Singleton. Show all posts

Wednesday, March 24, 2010

Singletons, Threads & Double Checked Locking

This blog entry extends on the first entry I wrote about Singletons. Today I try to explain the usage of Singletons in a multi-threaded environment.

A typical Singleton would look like the following:

MySingletonJava

This Singleton class would work perfectly fine in a single-threaded environment. But, how many Java based applications that you have worked on, are single-threaded? None, perhaps.

Can you see what’s terribly wrong with it when your application has multiple threads running simultaneously ??

Well, the answer lies in the way the instance is lazy initialized. The null-checking and initializing the instance need to be an atomic operation. Lets see what would happen if following sequence of events happen:

  • Thead A calls getInstance() for the first time. And checks whether instance is null or not. It finds it true and goes to execute line 11.
  • At this point, it is pre-empted by another thread: Thread B, which also calls getInstance(), checks for the instance null check, since it is not yet initialized, the private constructor is called and instance is now initialized with a state.
  • Thread A resumes control back and starts from where it left i.e line 11. Now the real problem occurs. Since it checked for the null-check on line 10 when it last run and found it to be true, so when it resumes execution, it will execute from line 11 and again initialize the instance and hence two objects would be created and the whole point of having a single object is violated.

Thus, we really need to do something about the situation. No problems, Synchronization comes to the rescue. Most of us (naive programmers) would tend to get rid of this problem by writing code like below:

MySynchronizedSingletonJava

The only change that occurs here is that we have made our static factory as synchronized method, which makes sure that no possible combination of interleaving of threads could create two objects like it did in the previous case. Although, this works fine but on close inspection, we find that synchronization is necessary only for the first time, and not needed later on (since instance will always be non-null later on) And synchronizing the whole method is thus uncalled for and pretty expensive. We must think of other ways of accomplishing this.

1. Do Not Lazy Initialize

If we do NOT need lazy initialization of the resource, then a perfect method to do away with synchronization would be:

Singleton1Java

Using this, we depend on the JVM’s capability to execute the static block as soon as the class is loaded first (when it is accessed or referred in code).

Thus, the VM makes sure that the instance is well initialized, before any thread tries to call getInstance() method. And since static blocks are executed only once, so no chance of creating more objects. One scenario that I could fail this approach is when this class is loaded again (perhaps by a different classloader in a different namespace)

Another way to write the above code would be:

Singleton2Java

However, I prefer the first way (with static blocks) that gives us more flexibility by allowing us to write a block of code instead of just calling the constructor.

2. Use Double Checked Locking

A very common, popular and misunderstood programming idiom that looks like the following and works with Java 1.5 and above only.

Singleton3Java

See how cleverly, we have limited the scope of synchronization here. The synchronization occurs only for the first time (when the instance is null), after that the synchronization never occurs as the instance is not null. This is what we needed. But you must make this variable as volatile to work it correctly (due to Java Memory Model implementation)

To better understand this programming idiom, I would suggest reading this and this.

I think its enough for one blog post. Any code corrections, new ideas and comments are welcome.

Sunday, July 12, 2009

Singleton Class in Java

What is Singleton ?

Many times we face situations in which we need to model an entity which can have only one Live instance at a time. Speaking in technical terms, we need to create a class which can be instantiated only once i.e. only one object can be created of that class during the scope of the entire application. Examples can be an instance of a Printer which can be used by many clients to print any document. But since we have only printer, so we must not allow the user/client to create more than one instance of the Printer class. Rather all of them must use the same instance in an synchronized manner.

A more common example could be a handle to the Database Connection Pool. We must have only 1 instance of the Pool Manager, which in turn can allocate database connections from the common pool of connections and can put them back after they are used. Having more than 1 instance of the Pool Manager can result in problems, which can be really difficult to debug.

Lets see how to make a Java Class that can be used as a Singleton

Method 1

Inside your class, keep a count of how many instances have been created so far in a static variable. Now, you can throw an Exception in your constructor, the moment a client tries to create more than one instance. Example code given below:

pic2

Method 2

Make your class’ constructor Private and keep another private instance variable which can call the constructor. Create a public getter function for the retrieving the singleton object as shown below:

pic1

One problem with this approach is that one can use Reflection API to invoke the private constructor and thus the whole concept of Singleton class is violated as shown below:

pic3

This can be overcome by throwing an exception in the MySingleton constructor when it is called more than once (as we have done in first Method)

Another Caveat

Can you think of any more way the above code can be broken? By breaking, I mean can you create two instances of the above class.

Hint: Serialization !!

Answer: If your class implements Serializable interface or inherits some class which implements this interface, then this code can be broken by first serializing the object (saving the state of the object to some file) and then de-serializing it (retrieving back the original state). If we do not override readResolve() method as shown below:

pic4

To the best of my knowledge, now I think there is no way you can create another object with all these checks implemented. Please feel free to comment & discuss this and point out any problems with above mentioned techniques.