Monday, January 20, 2014

Why Singleton design pattern is still a good interview question to Java developers

Why every interviewer asks about singleton design pattern?
Well the answer could be either,
  1. That's what the interviewer knows to ask for.
  2. Or its a good way to start and branch into several other discussions.
  3. Or its one of the simplest design pattern and a controversial one in terms of usage.
What ever the reason may be, we better know it.

What is Singleton
Singleton is categorized under "Creational design pattern" and part of Gang of Four design pattern.  Singleton is a design pattern which suggests only one instance of a class for the entire application at any condition. There are several ways to achieve this, and be assured that most of answers you say may not convince the interviewer and he can over rule the solution.

Ways to do it
Before getting into the details are there any examples of Singleton to be used in real scenarios?  Yes, java Runtime, Logger, Service locators of JEE pattern follows singleton.  Now, we shall look into the most common ways to implement Singleton.

Singleton - Eager Initialization Example
As the name states in this approach the instance is "eagerly" created before it is expected/asked for.  It means the class will be initialized during the application startup.
In this example the interviewer would be interested in asking, What if the instance of this class is not required at all.

Yes it is a drawback that the instance is created even if it is not required. And that would be an issue only if this object is large, or else it is the best to leave it as is.  Lets say the interviewer says,  it is a large object and I do not want it to be eager loaded.  Well the next section describes you how you could write Singleton with lazy initialization.

Singleton - Lazy Initialization Example
Lazy loading is an interesting topic in programming, it means creating the object in a delayed(lazy) way. Generally any expensive process could adapt lazy style. To make our singleton lazy we have initialize the instance variable only when it is expected.
You could see the instance variable is assigned with the object when it is null and then on the same variable is reused. Take a closer look into line 10, it ensures thread safety.  If you are just writing just the pseudo code, there could be a question what would you synchronize as you haven't initialized the object yet. We synchronize the block with the class here.

Next is the volatile keyword for the instance variable, do we need that? If so why.
Yes it is absolutely required or you may run in into out of order write error scenario. ie. The reference is returned even before the object is constructed (in other words the memory is allocated but the constructor code isn't finished execution). Also volatile keyword helps as the concurrency control tool in a multi-threaded application.

Singleton - Enum way Example
Easiest of the ways, by default Enums are thread safe and ensures single instance.
For an interview I would not suggest this approach,  since it would finish up the question pretty quick.  You don't want to do that,  better hold the interviewer on the topic you know well. In terms of implementation I would suggestion the Enum way or the one that is discussed in the next section.

Singleton - Bill pugh way Example
William Pugh co-author of findbugs static code analyzing tool, on his research suggested the following way while implementing singleton.
You could witness  SingletonHolder, SingletonBillPughExample will not be initialized until getInstance() is invoked.

3 comments:

  1. Actually, your eager initialization does not need volatile, because all static variables are initialized during the class-load phase in the classloader which is by design, single threaded (and gated with synchronization), and therefore cannot be accessed (getInstance() will not be dispatched) until the class load is complete and the field is fully initialized and has been gated by the synchronization completing.

    However it *is* important that it be made "final" for this variance to be fully considered true - something your example does not have.

    ReplyDelete
    Replies
    1. Yes you are right, I apologize for the incorrect example. I have fixed it now, eager loading doesn't need volatile, instead it has to be final. It has to be volatile for lazy loading. I appreciate you for leaving this comment.

      Delete
  2. Isn't there an issue in the Lazy initialization sample with the possibility of double construction since the null check is outside the lock?

    I think the null check should be repeated inside the lock.

    ReplyDelete