'Java Singleton Pattern' - This topic is very interesting and touches basic concept of java and good understanding of this pattern will help to clear java technical interviews.
Implementation of a singleton pattern must satisfy the single instance and global access principles. It requires a mechanism to access the singleton class member without creating a class object and a mechanism to persist the value of class members among class objects. The singleton pattern is implemented by creating a class with a method that creates a new instance of the class if one does not exist. If an instance already exists, it simply returns a reference to that object. To make sure that the object cannot be instantiated any other way, the constructor is made private. Note the distinction between a simple static instance of a class and a singleton: although a singleton can be implemented as a static instance, it can also be lazily constructed, requiring no memory or resources until needed. Another notable difference is that static member classes cannot implement an interface, unless that interface is simply a marker. So if the class has to realize a contract expressed by an interface, it really has to be a singleton.
The singleton pattern must be carefully constructed in multi-threaded applications. If two threads are to execute the creation method at the same time when a singleton does not yet exist, they both must check for an instance of the singleton and then only one should create the new one. If the programming language has concurrent processing capabilities the method should be constructed to execute as a mutually exclusive operation.
The classic solution to this problem is to use mutual exclusion on the class that indicates that the object is being instantiated. Unfortunately, in Java hacking singleton cannot be solved, unless one uses fully static class. See the sections below. Double check locking is famous idiom and due to that there were java memory model changes in java 1.5 release. let's see how it happens before java 1.5 release even if you declare instance as volatile.
Double Check Lock[DCL]
In very simple words DCL happens like this. suppose 1) Two threads A and B enter into getInstance() method. 2) Both Thread A and B enters into line number 0 and both cross this as instance is null. 3) Assume Thread A gets lock and on Singleton.class at line no. 1 and Thread B gets block here to get Singleton.class monitor lock. 4) Thread A moves to line no 3 and creating the instance of Singleton class and this time Thread C comes and calls getInstance() and it saw that instance is not null and Thread A is assigned the space but object is still not properly constructed and method getInstance() returns the partial constructed instance to Thread C at line 4. |
Here is famous article on this - DCL broken.
Nice presentation before Java memory model changes in java 1.5 by Jeremy Manson, William Pugh.
The original semantics for volatile guaranteed only that reads and writes of volatile fields would be made directly to main memory, instead of to registers or the local processor cache, and that actions on volatile variables on behalf of a thread are performed in the order that the thread requested. In other words, this means that the old memory model made promises only about the visibility of the variable being read or written, and no promises about the visibility of writes to other variables. While this was easier to implement efficiently, it turned out to be less useful than initially thought.
Singleton class with making instance as volatile
Singleton class with making instance as volatile
Singleton class with Initialize on demand Holder Class Idiom
Singleton class with ENUM