This week's book giveaway is in the OCAJP forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide 1Z0-808 and have Jeanne Boyarsky & Scott Selikoff on-line! See this thread for details.
The Singleton Pattern is one of the commonly used design templates when there needs to be a control on how an object can be created. This design pattern proposes that at any time there can only be one instance of a singleton (object) created by the JVM. The Singleton class�s default constructor is made private, which prevents the direct instantiation of the object by others (Other Classes). One such scenario where it might prove useful is when we develop the Java Help Module in a project. JavaHelp is an extensible, platform-independent help system that enables authors and developers to incorporate online help into applications. Since at any time we can do only with one main Help object and use the same object in different screens, Singleton Pattern suits best for its implementation. Implementing the Singleton Pattern To implement this design pattern we need to consider the following 4 steps:
Step 1: Provide a default Private constructor
Step 2: Create a Method for getting the reference to the Singleton Object
We write a public static getter or access method to get the instance of the Singleton Object at runtime. First time the object is created inside this method as it is null. Subsequent calls to this method returns the same object created as the object is globally declared (private) and the hence the same referenced object is returned.
Step 3: Make the Access method Synchronized to prevent Thread Problems.
It could happen that the access method may be called twice from 2 different classes at the same time and hence more than one singleton object being created. This could violate singleton pattern principle. In order to prevent the simultaneous invocation of the getter method by 2 threads or classes simultaneously we add the synchronized keyword to the method declaration
Step 4: Override the Object clone method to prevent cloning. We can still be able to create a copy of the Object by cloning it using the Object�s clone method. This can be done as shown below
This again violates the Singleton Design Pattern's objective. So to deal with this we need to override the Object�s clone method which throws a CloneNotSupportedException exception.
The below program shows the final Implementation of Singleton Design Pattern in java, by using all the 4 steps mentioned above.
First, I'd be suspicious of this: Since at any time we can do only with one main Help object and use the same object in different screens, Singleton Pattern suits best for its implementation. It's common to think Singleton is a good solution when it really isn't the best. I don't know enough about JavaHelp or your application to say Singleton isn't appropriate, but take the time to dig in and be certain that creating a new object every time you need one is a problem.
Second, Singleton solutions that test for null like yours are unsafe in threaded environments. You can synchronize the whole getInstance() method for some balance of safety and performance. I prefer to just instantiate the single instance ahead of time:
No if tests, no thread issues, no synchronized blocks.
This does have the potential to create the instance earlier than other techniques, say the first time you call a static method on the Singleton class whether you wanted an instance or not. I have never lost any sleep over this question.
Finally, preventing clone() is going toward enforcing the single instance instead of just enabling people to share an instance. (To go this route, you might have to prevent serialization, too.) I lean more toward enabling people than forcing them, though it does run the risk of somebody breaking the rules. Back to the original question: how serious is that? How much effort should we put into enforcement of the design?
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Following on from Stan's comments, I'm slightly worried that the tutorial is missing any advice on, or examples of, when not to use a Singleton.
This is (unfortunately) a problem common to a lot of stuff written about patterns, and to Singleton in particular. All patterns have some situations for which they are suitable, and some situations for which they are not suitable. Giving one recommendation of a situation for which this pattern sounds applicable does not provide any help in when to avoid it.
As it happens, there are plenty of messages in this forum where people discuss at length the applicability of Singleton, and the consensus seems to be that it is much less applicable than it would appear on the surface. Some people would even go so far as to classify it as an "anti-pattern" because it is misused so often.
With this in mind, any write-up of Singleton really has a responsibility to discuss the many situations and possibilities in which it might seem appropriate but is likely to cause problems in the longer term. Personally. I'd also like to see some discussion of alternatives (such as just creating a single instance with no special protection and passing it around where needed) which address some of the problems with Singleton to help developers make sensible choices.