Singleton Design Pattern

This pattern is all about of creating one and only one instance of an object. Yes it sounds it is simple but once you are doing it wrong you will see some surprises with your programs outputs and would hardly know what is going wrong. There are many objects we only need one of: thread pools, caches, dialog boxes, site configuration objects, controllers between software components, objects that handle preferences and registry settings, objects used for logging, and objects that act as device drivers to devices like printers and graphics cards. In fact, for many of these types of objects, if we were to instantiate more than one we’d run into all sorts of problems like incorrect program behavior, overuse of resources, or inconsistent results.

In many ways, the Singleton Pattern is a convention for ensuring one and only one object is instantiated for a given class. If you’ve got a better one, the world would like to hear about it; but remember, like all patterns, the Singleton Pattern is a time-tested method for ensuring only one object gets created. The Singleton Pattern also gives us a global point of access, just like a global variable, but without the downsides.

Disadvantages:

if you assign an object to a global variable, then you have to create that object when your application begins (This is actually implementation dependent. Some JVM’s will create these objects lazily.). What if this object is resource intensive and your application never ends up using it? As you will see, with the Singleton Pattern, we can create our objects only when they are needed. If you’ve got a good handle on static class variables and methods as well as access modifiers, it’s not. But, in either case, it is interesting to see how a Singleton works, and, as simple as it sounds, Singleton code is hard to get right. Just ask yourself: how do I prevent more than one object from being instantiated? It’s not so obvious, is it?

Now lets see it in action but remember for now this is not thread-safe:

public class Singleton {
private static Singleton uniqueInstance;
private Singleton() {}

public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
  • The getInstance() method gives us a way (actually the only way) to access or create the singleton object. It is static and public so this method is accessible all over the program like Singleton.getInstance();. Every class or method will and must access it in this way. This is just as easy as accesing a global variable, but we get benefits like lazy instantiation from the Singleton.
  • The private constructor ensures that this class can be initialized only within itself.(you would see it coming ha?)
  • Static uniqueInstance object hold the unique Class object.
  • There could be (and will) other useful methods and fields with this class but we brought a simple one here.

The story begins here:

public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}

each time the getInstance() method called we have to check if it is already created since we want and there must be only one instance of the class. If it is not created just create it and finally give me the unique (in this case it may not be as you will see) object created now or already created.

But what if…?!

public static Singleton getInstance() {
if (uniqueInstance == null) {// 2 threads checking if null
uniqueInstance = new Singleton();
}
return uniqueInstance;
}

if there are two (or more) threads in line 2 both will see that uniqueInstance is null (at the first time) and both will initialize this which will end up with two instances of a unique object.

We must ensure that only one thread must use this method at any given time so we can fix that by:

public static synchronized Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}

Good point, and it’s actually a little worse than you make out the only time synchronization is relevant is the first time through this method. In other words, once we’ve set the uniqueInstance variable to an instance of Singleton, we have no fin-tiler need to synchronize this method. After the first time through, synchronization is totally unneeded overhead! Synchronization comes with performance decrease though you need it once this is totally bad idea but will work.

Can we improve multi-threading?

For most Java applications, we obviously need to ensure that the Singleton works in the presence of multiple threads. But, it looks fairly expensive to synchronize the getInstance() method, so what do we do?
Well we have a few options…

  1. Do nothing if the performance of getInstance() isn’t critical to your application. That’s right; if calling the getInstance() method isn’t causing substantial overhead for your application, forget about it. Synchronizing getInstance() is straightforward and effective. Just keep in mind that synchronizing a method can decrease performance by a factor of 100, so if a high traffic part of your code begins using getInstance(), you may have to reconsider.
  2. Move to an eagerly created instance rather than a lazily created one
    If your application always creates and uses an instance of the Singleton or the overhead of creation and runtime aspects of the Singleton are not onerous, you may want to create your Singleton eagerly, like this:
public class Singleton {
private static Singleton uniqueInstance = new Singleton();
private Singleton() {}
<p style="text-align: justify;">public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;</p>
<p style="text-align: justify;">}</p>
<p style="text-align: justify;">}</p>
<p style="text-align: justify;">

Using this approach, we rely on the JVM to create the unique instance of the Singleton when the class is loaded. The JVM guarantees that thie instance will be created before any thread accesses the static uniqueInstance varible.

3. Use “Double-checked locking” to reduce the use of synchronization in getInstance()

With double-checked locking, we first check to see if an instance is created, and if not, THEN we synchronize. This way we only synchronize the first time through, just what we want. Let’s check out the code:

(the volatile keyword ensures that multiple threads handle uniqueInstance variable correctly when it is being initialized to the Singleton instance.)

public class Singleton {
private volatile static Singleton uniqueInstance;
private Singleton() {}

public static Singleton getInstance() {
if (uniqueInstance == null) {
synchronized(Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}

return uniqueInstance;
}

in the 5. line we enter synchronized block if only the instance has not been created. If it is not created we must ensure that only one thread will cerate the instance with new keyword but however there may be a thread just left the sync block and initialized the Singleton object  which makes us checking the instance is null again in line 7.

If performance is an issue in your use of the getInstance() method then this method of implementing the Singleton can drastically reduce the overhead.

To Sum Up:

  • The Singleton Pattern ensures you have at most one instance of a class in your application.
  • The Singleton Pattern also provides a global access point to that instance.
  • Java’s implementation of the Singleton Pattern makes use of a private constructor, a static method combined with a static variable.
  • Examine your performance and resource constraints and carefully choose an appropriate Singleton implementation for multithreaded applications (and we should consider all applications multithreaded!).
  • Beware of the double-checked locking implementation; it is not thread-safe in versions before Java 2, version 5.
  • Be careful if you are using multiple class loaders; this could defeat the Singleton implementation and result in multiple instances.
  • If you are using a JVM earlier than 1.2, you’ll need to create a registry of Singletons to defeat the garbage collector.
  • Furthermore you can search for enum as singleton in java. Enums are implicitly thread-safe so you won’t need to worry about locking etc. and bonus: enum singletons handle serialization by themselves.

Q&A

Q: For such a simple pattern consisting of only one class, Singletons sure seem to have some problems.
A: Well,we warned you up front! But don’t let the problems discourage you; while implementing Singletons correctly can be tricky, after reading this blog you are now well informed on the techniques for creating Singletons and should use them wherever you need to control the number of instances you are creating.


Q: Can’t I just create a class in which all methods and variables are defined as static? Wouldn’t that be the same as a Singleton?
A: Yes, if your class is self-contained and doesn’t depend on complex initialization. However, because of the way static initializations are handled in Java, this can get very messy, especially if multiple classes are involved. Often this scenario can result in subtle, hard to find bugs involving order of initialization. Unless there is a compelling need to implement your “singleton”this way, it is far better to stay in the object world.


Q: What about class loaders? I heard there is a chance that two class loaders could each end up with their own instance of Singleton.
A: Yes, that is true as each class loader defines a namespace. If you have two or more class loaders, you can load the same class multiple times (once in each classloader). Now, if that class happens to be a Singleton,then since we have more than one version of the class, we also have more than one instance of the Singleton. So, if you are using multiple class loaders and Singletons, be careful. One way around this problem is to specify the classloader yourself.


Q: I’ve always been taught that a class should do one thing and one thing only. For a class to do two things is considered bad OO design. Isn’t a Singleton violating this?
A: You would be referring to the “One Class, One Responsibility” principle, and yes, you are correct, the Singleton is not only responsible for managing its one instance (and providing global access), it is also responsible for whatever its main role is in your application. So,certainly it can be argued it is taking on two responsibilities. Nevertheless, it isn’t hard to see that there is utility in a class managing its own instance; it certainly makes the overall design simpler. In addition, many developers are familiar with the Singleton pattern as it is in wide use. That said, some developers do feel the need to abstract out the Singleton functionality.


Q: I wanted to subclass my Singleton code, but I ran into problems. Is it okay to subclass a Singleton?
A: One problem with subclassing Singleton is that the constructor is private. You Can’t extend a Class with a private constructor. So,the first thing you’ll have to do is change your constructor so that it’s public or protected. But then, it’s not really a Singleton anymore, because other classes can instantiate it. If you do change your constructor, there’s another issue. The implementation of Singleton is based on a static variable, so if you do a straightforward subclass, all of your derived classes will share the same instance variable. This is probably not what you had in mind. So, for subclassing to work, implementing registry of sorts is required in the base class. Before implementing such a scheme, you should ask yourself what you are really gaining from subclassing a Singleton. Like most patterns, the Singleton is not necessarily meant to be a solution that can fit into a library. In addition, the Singleton code is trivial to add to any existing class. Last, if you are using a large number of Singletons in your application, you should take a hard look at your design. Singletons are meant to be used sparingly.


Q: I still don’t totally understand why global variables are worse than a Singleton.
A: In Java, global variables are basically static references to objects. There are a couple of disadvantages to using global variables in this manner. We’ve already mentioned one:the issue of lazy versus eager instantiation. But we need to keep in mind the intent of the pattern: to ensure only one instance of a class exists and to provide global access. A global variable van provide the latter, but not the farmer. Global variables also tend to encourage developers to pollute the namespace with lots of global references to small objects. Singletons don’t encourage this in the same way, but van be abused nonetheless.

Reklamlar

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Connecting to %s