Singleton pattern is a creational design pattern. It ensures a class has only one instance created, and provides a global point of access to it. The implementation includes just-in-time initialization and initialization on first use.
Singleton class is one of the simplest design patterns, but it poses many challenges. One of the key challenge is how to keep Singleton class as Singleton?
Singleton related interview questions
- What is Singleton class? When to use it?
- Write code for getInstance() method of a Singleton class in Java
- What is lazy and eager loading of Singleton? How to implement them.
- What is double checked locking in Singleton?
- Why Singleton is Anti pattern?
- Can you replace Singleton with Static Class in Java?
- Difference between Singleton and Static Class in java? Any pro / cons?
Implementation 1
The singleton instance is initialized during class loading. Since Singleton instance is static and final variable, it is initialized when class is loaded into memory. In this solution, the creation of instance is thread-safe.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package net.tecbar.designpattern.singleton; public class Singleton1 { // initialized during class loading private final static Singleton1 INSTANCE = new Singleton1(); private Singleton1() {} public static Singleton1 getInstance() { return INSTANCE; } public void sayHello() { System.out.println("Hello"); } } |
Usage will be
1 |
Singleton1.getinstance().sayHello(); |
Implementation 2
A singleton instance is created by synchronize getInstance() method, and is thread-safe. However, it is unnecessarily expensive due to cost of synchronization at each call.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package net.tecbar.designpattern.singleton; public class Singleton2 { private static Singleton2 INSTANCE = null; private Singleton2() { } public static synchronized Singleton2 getInstance() { if(INSTANCE == null) { INSTANCE = new Singleton2(); } return INSTANCE; } public void sayHello() { System.out.println("Hello"); } } |
Implementation 3
It is an implementation of double checked locking of Singleton which will minimize the cost of synchronization by locking critical section of code (see example code).
It is noted that we need make INSTANCE a volatile variable. Otherwise, it is still broken as another thread can see a half initialized instance of Singleton.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package net.tecbar.designpattern.singleton; public class Singleton3 { // volatile to indicate it will be modified by different threads private volatile static Singleton3 INSTANCE = null; private Singleton3() { } public static Singleton3 getInstance() { if (INSTANCE == null) { synchronized (Singleton3.class) { if (INSTANCE == null) { INSTANCE = new Singleton3(); } } } return INSTANCE; } public void sayHello() { System.out.println("Hello"); } } |
Implementation 4
It is an idea approach to utilize enum which can have its own methods and properties.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package net.tecbar.designpattern.singleton; public class Singleton4 { public static void main(String[] args) { SingletonEnum.uniqueInstance.singletonOperation(); } } enum SingletonEnum { uniqueInstance; public void singletonOperation(){ System.out.println("hello world"); } } |
Pingback: Software Design Patterns