Singleton pattern is probably one of the most common design patterns being used in software development processes. It is also one of the simplest patterns from implementation and use perspective.
In this article I tried to light up some of the subtle facts regarding singleton pattern especially in java context. The aim of this document is to explore singleton pattern in depth especially the unheeded facts involved in it.
2 Singleton Pattern
2.1 A Quick Introduction:
Before putting forward some of the untouched features of Singleton pattern, let’s see a brief introduction of singleton pattern. Note that, although the definition quoted below is the most common definition of single pattern, the same is updated / changed below in this article when we explored singleton pattern in depth.
Definition: Singleton pattern assured that there will always be a single (one) instance of the class present in the run time environment.
Although, the above definition is the simplest to define singleton pattern, it indeed is neither complete nor correct. Before we explore the incompleteness and incorrectness of this definition, let’s see a simple way to implement singleton pattern (as per above definition) in java:
public class Singleton {
//The single instance of the class.
private static Singleton instance;
//Private constructor to avoid creation of multiple instances //from outside
private Singleton(){
}
//Static method returning the single instance of the class.
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Code Listing 1
The above code is as simple as the above definition. It explored a static method to get the single instance of the class. Also note that the constructor is private hence the class can’t be instantiated from outside. This will ensure that there will always be one instance of this class.
2.2 It’s Not Singleton Instance Pattern:
So the first incorrect word in the above definition is ‘single instance’. The pattern doesn’t restrict itself to the single instance, but to a single object (class or instance).
Look at the code below:
public final class SingletonClass {
//private constructor
private SingletonClass() {
}
//Static method
public static void method1(){
}
//All remaining methods are static
}
Code Listing 2
In the above code the class is final with optional private constructor and all methods as static. This will ensure that there will always be one class object corresponding to this class with no instance. This is another flavor of singleton pattern.
2.3 Java Doesn’t Support True Singleton Patterns:
Yes, this is a fact: java doesn’t support singleton pattern to its true flavor. So, the next incorrect word in the above definition is ‘run time environment’. Let’s discuss the issues involved in true implementation of singleton pattern in java.
1. Issues with Class loaders:
In java, a class loaded in JVM is recognized not only on the basis of its fully qualified name but also on the basis of the class loader responsible for loading it in the JVM. Thus if a singleton class is loaded with different class loader (the word class loader here refer to application/system class loaders or user defined class loaders extending application/system class loaders and also assuming that they are not in the same hierarchy), we will have that many instances (objects) of the class in JVM. In other words, while loading a class the JVM checks whether the same class is loaded by any class loader in the hierarchy or not. The class will be loaded only if none of the class loaders (in the same hierarchy) loaded the class. But incase the class loader is changed the same class will be reloaded and instantiated again provided the new class loader is not in the same hierarchy. Hence you may have multiple instances of a singleton class in the JVM using multiple class loaders.
Although this is a fact and has no solution, still it is an unheeded fact simply because of 2 reasons:
- Rarely we write our own class loader and use it to load the classes.
- Even in cases where a programmer writes his/her own class loader, most of the time he/she follows the same hierarchy.
Still it becomes a troubling issue many times for e.g. incase of web servers which uses new class loader for each Servlet even in the same web application.
2. Issues with Serialization:
Imagine a scenario where singleton class implements serializable interface. In such cases one can serialize and de-serialize the singleton instance of the class to get another instance in the same JVM. Although this is a rare situation and with proper implementation it can always be avoided, still it questions the implementation of true singleton pattern in java.
3. Issues with Threading:
In the code listing 1 above, imagine that multiple threads access the singleton class at the same time to get the instance for the first time. It might happen that these threads executes the line ‘if (instance == null)’ of getInstance() method at the same. This may result in creation of multiple instances at the same time. Although this is a result of wrong implementation of the entry method i.e. getInstance() but still depict the threading issues in java related with singleton pattern implementation. The above mentioned problem can be solved in 2 ways.
- Initialize the variable ‘instance’ at the time of declaration. But this will be against the optimized rule of lazy loading where the instance of the class is not creating unless it is required.
- The 2nd and most effective solution is use of either ‘synchronized’ block or method.
2.4 Few More Subtle Points Regarding Singleton pattern:
1. Issues with browser JVM incase of applets:
Although the issues vary from browser to browser, I am picking the most common MS Internet explorer and 2 most commonly faced issues related with singleton pattern incase of applets:
- If your page contains applet(s) which uses singleton patterns and you open a new window from this page (for e.g. using window.open() in java script), the same JVM will be shared between the parent and child browsers. In other words, the child browser will share the JVM of its parent and hence if the child browser too contains applet(s) and using the singleton class, note that the parent and child browser’s applet will use the same instance. Sometime this is a desirable condition but many a times it is categorized as a problem.
- On the other side of the coin there is an issue related with different frames on the same page. If your page is divided into frames and each frame has applet(s) using singleton pattern, then each frame will have its own JVM and hence the singleton instance will be per frame instead of per page.
2. Issues with distributed application:
In distributed environment, the application is deployed in fractions on different JVM and hence the singleton instances are not same throughout the code. Hence it is highly advisable to use singleton pattern in distributed environment in such a way that the same is restricted to one runtime environment. In other words the use of the singleton class should be logically categorized based on the code deployed on a single JVM instead of using the same singleton class across different runtime environment.
3. Issues with clustered environment:
Clustered environment, where multiple servers are used to serve the client requests, also brings lots of issues related with singleton classes. This becomes more prominent when the ‘Sticky Session’ approach is used where any server in the cluster can serve any request irrespective of the condition whether it or any other server has served the last request from the same client. In ‘Sticky Session’ approach all live sessions are replicated to all servers in the cluster and hence singleton instance creates problem when the session is replicated between servers. Thus one must be very cautious while using singleton pattern in clustered environment.
3 Conclusion:
Although one of the most simple and commonly used design pattern, singleton pattern has many subtle issued associated with it especially in java platform. One must take a judicious decision while using pattern and should considered all possible consequences before implementing singleton pattern in the application.
3 comments:
Hi,
A very good eye opener blog :)
Thanks
Sudarshan
Came across some more use cases while digging the Singleton pattern.
Check this : http://www.ibm.com/developerworks/java/library/j-dcl.html#author
-Poonam.
Post a Comment