Singleton pattern is a design solution where you can:
- 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.
In computer programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed.
This method uses double-checked locking, which should not be used prior to J2SE 5.0 as it is vulnerable to subtle bugs.
If the program will always need an instance, or if the cost of creating the instance is not too large in terms of time/resources, the programmer can switch to eager initialization, which always creates an instance.
This method has a number of advantages:
- the instance is not constructed until the class is used;
- there is no need to synchronize the getInstance() method, meaning all threads will see the same instance and no (expensive) locking is required;
finalkeyword means that the instance cannot be redefined, ensuring that one (and only one) instance ever exists.
Static block initialization
The static blocks are executed during the loading of class and even before the constructor is called so the programmer can use this feature in the singleton pattern.
This method has one drawback. Suppose there are 5 static fields in class and application code needs to access only 2 or 3, for which instance creation is not required at all. So, if we use this static initialization, we will have one instance created though we require it or not.
Bill Pugh solution
LazyHolder is loaded on the first execution of
BillPughSingleton.getInstance() or the first access to
LazyHolder.INSTANCE, not before.
This type of implementation recommend the use of
enum. Enum, as written in java docs, provide implicit support for thread safety and only one instance is guaranteed. This is also a good way to have singleton with minimum effort.
The public method can be written to take any desired types of arguments; a single
String argument is used here as an example.
This approach implements the singleton by taking advantage of Java’s guarantee that any
enum value is instantiated only once in a Java program. Since Java enum values are globally accessible, so is the singleton, initialized lazily by the classloader. The drawback is that the
enum type is somewhat inflexible.