Singleton is a class which has only one instance in whole
application. This design pattern suggests that at any time there can only be
one instance of a Singleton class object created by the JVM.
There are many classes in JDK which is implemented using
Singleton pattern like java.lang.Runtime which provides getRuntime() method to
get access of it and used to get free memory
and total memory in Java.
When to use Singleton?
- Singleton pattern used when we want to allow only a single instance of a class can be created inside our application. Using this pattern ensures that a class only have a single instance by protecting the class creation process, by setting the class constructor into private access modifier.For example, you can use it to create a connection pool. It’s not wise to create a new connection every time a program needs to write something to a database; instead, a connection or a set of connections that are already a pool can be instantiated using the Singleton pattern.
- Ensure that only one instance of a class is created
- Provide a global point of access to the object
- Allow multiple instances in the future without affecting a singleton class's clients
Different ways to create a Singleton class in Java
Lazy Initialization is a technique where one postpones
the instantiation of an object until its first use. In other words the instance
of a class is created when it’s required to be used for the first time. The
idea behind this is to avoid unnecessary instance creation. We are going to explore each and every method to create a Singleton.
Singleton by synchronizing getInstance() method
To address
the issue of multiple threads creating more than one instance of the singleton,
make getInstance() a synchronized method.
- Singleton has a static variable to keep its single instance.
- You need to set the class constructor into private access modifier. Hence you will not allow any other class to create an instance of this singleton because they have no access to the constructor.
- getInstance() method should be called to fetch the Singleton class instance.
- When we use our singleton in a multi-threaded application we need to make sure that instance creation process not resulting more than one instance, so we add a synchronized keywords to protect more than one thread access this method at the same time.
- It is also advisable to override the clone() method of the java.lang.Object class and throw CloneNotSupportedException so that another instance cannot be created by cloning the singleton object.
Singleton with public static final field initialized during class loading
Singleton instance is static
and final
variable it initialized when class is first loaded into memeory so
creation of instance is inherently thread-safe.
In this approach the methods are not synchronized instead
the instance creation code is put in a synchronized block
In the below code there are two null checks- one outside the
synchronized block and one within it. The synchronized block is executed at
most once and any other thread trying to get instance would have to wait until
the instantiation to complete.
Using Enums (From Java 5 on-wards)
Creatinon of Enum instance is thread-safe by default you
don't need to worry about double checked locking.
In summary, given the Serialization and thread-safety
guaranteed and with couple of line of code enum Singleton pattern is best way
to create Singleton in Java 5 world
Which option is better: synchronized complete
getInstance() method or just critical section?
Synchronization is costly and when
you apply this on whole method than call to getInstance() will be synchronized
and contented. Since synchronization is only needed during initialization on
singleton instance, to prevent creating another instance of Singleton,
It’s better to only synchronize critical section and not whole method.
Double checked locking is a
technique to prevent creating another instance of Singleton when call to
getInstance() method is made in multi-threading environment. In Double checked
locking pattern as shown in below example, singleton instance is checked two
times before initialization.
Double checked locking should only be used when you have
requirement for lazy initialization otherwise use Enum to
implement singleton or simple static final variable.
Singleton Pattern v/s Static class
- Both Singleton pattern and static class share some similarities .Both can be used without creating object and both provide only one instance, at very high level it looks that they both serve the same purpose.
- One key point to be remembered Singleton gives you object whereas Static class gives you methods.For an Example: java.lang.Math, which contains lots of utility methods for various maths function e.g. sqrt(). While Singleton classes are those, which has only one instance during application life cycle like java.lang.Runtime.
- You can also choose to use static method, if you need to combine bunch of utility method together. Anything else, which requires singles access to some resource, should use Singleton design pattern.
- Static class provides better performance than Singleton pattern, because static methods are bonded on compile time.
- Static classes are hard to mock and consequently hard to test than Singletons, which are pretty easy to mock and thus easy to test. It’s easier to write JUnit test for Singleton than static classes, because you can pass mock object whenever Singleton is expected, e.g. into constructor or as method arguments.
- Singleton classes can be lazy loaded if its an heavy object, but static class doesn't have such advantages and always eagerly loaded.
- If we talk about java.lang.Runtime, which is a Singleton in Java, call to getRuntime() method return different implementations based on different JVM, but guarantees only one instance per JVM, had java.lang.Runtime an static class, it’s not possible to return different implementation for different JVM.
Please find the link below to see the running example:
https://docs.google.com/file/d/0BzbinC6y3sGqdmFwOGVJY18xcTA/edit?usp=sharing
No comments:
Post a Comment