What are the Singleton Design Pattern and its implementation in Java?
Singleton is a design pattern which ensures there is only one object of
the class is created for the entire application.
Step to make the Singleton pattern:
1. Declare
constructor as private.
2. Create
a private static final field and assign an instance of the same class.
3. Create
a public static method which returns the reference of the instance of the same
class.
1: Classical Implementation
|
Here we have declared getInstance() static so that we can call it
without instantiating the class. The first time getInstance() is called it
creates a new singleton object and after that, it just returns the same object.
Note that Singleton obj1 is not created until we need it and call getInstance()
method. This is called lazy instantiation.
The main problem with the above method is that it is not threaded safe.
Consider the following execution sequence.
This execution sequence creates two objects for the singleton. Therefore
this classic implementation is not thread-safe.
2: make getInstance() method synchronized
|
Here using synchronized makes sure that only one thread at a time can
execute getInstance().
The main disadvantage of this is method is that using synchronized every time while creating the singleton object is expensive and may decrease the performance of your program. However, if performance of getInstance() is not critical for your application this method provides a clean and simple solution.
The main disadvantage of this is method is that using synchronized every time while creating the singleton object is expensive and may decrease the performance of your program. However, if performance of getInstance() is not critical for your application this method provides a clean and simple solution.
3: Eager Instantiation
|
Here we have created an instance of a singleton in a static initializer.
JVM executes static initializer when the class is loaded and hence this is
guaranteed to be thread-safe. Use this method only when your singleton class is
light and is used throughout the execution of your program.
4: Use Double-Checked Locking
If you notice carefully once an object is created synchronization is no
longer useful because now obj1 will not be null and any sequence of operations
will lead to consistent results.
So we will only acquire a lock on the getInstance() once when the obj1 is null. This way we only synchronize the first way through, just what we want.
We have declared the obj1 volatile which ensures that multiple
threads offer the obj1 variable correctly when it is being initialized to
Singleton instance. This method drastically reduces the overhead of calling the
synchronized method every time.
So we will only acquire a lock on the getInstance() once when the obj1 is null. This way we only synchronize the first way through, just what we want.
class Singleton {
|
private volatile static Singleton obj1;
|
private Singleton()
{
|
}
|
public static Singleton
getInstance() {
|
if (obj1== null)
{
|
synchronized (Singleton.class)
{
|
if (obj1== null)
|
obj1= new Singleton();
|
}
|
}
|
return obj1;
|
}
|
}
|
No comments:
Post a Comment