Singlton pattern
An implementation of singleton class should have following properties:
It should have only one instance :
- It should have only one instance: This is done by providing instance of class from within the class. Outer classes or subclasses should be prevented to create the instance. This is done by making the constructor private in java so that no class can access the constructor and hence cannot instantiate it.
- Instance should be globally accessible : Instance of singleton class should be globally accessible so that each class can use it. In java it is done by making the access-specifier of instance public.
//A singleton class should have public visiblity
//so that complete application can use
public class GFG {
//static instance of class globally accessible
public static GFG instance = new GFG();
private GFG() {
// private constructor so that class
//cannot be instantiated from outside
//this class
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
Singleton class can be instantiated by two methods:
Early initialization : In this method, class is initialized whether it is to be used or not. Main advantage of this method is its simplicity. You initiate the class at the time of class loading. Its drawback is that class is always initialized whether it is being used or not.
Lazy initialization : In this method, class in initialized only when it is required. It can save you from instantiating the class when you don’t need it. Generally lazy initialization is used when we create a singleton class.
Examples
Eager initialization:
// Java code to create singleton class by
// Eager Initialization
public class GFG
{
// public instance initialized when loading the class
public static GFG instance = new GFG();
private GFG()
{
// private constructor
}
}
2
3
4
5
6
7
8
9
10
11
12
13
Pros:
Very simple to implement. No need to implement getInstance() method. Instance can be accessed directly. Cons:
May lead to resource wastage. Because instance of class is created always, whether it is required or not. CPU time is also wasted in creation of instance if it is not required. Exception handling is not possible.
Using static block
// Java code to create singleton class
// Using Static block
public class GFG
{
// public instance
public static GFG instance;
private GFG()
{
// private constructor
}
{
// static block to initialize instance
instance = new GFG();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Pros:
Very simple to implement. No need to implement getInstance() method. Instance can be accessed directly. Exceptions can be handled in static block. Cons:
May lead to resource wastage. Because instance of class is created always, whether it is required or not. CPU time is also wasted in creation of instance if it is not require
Lazy initialization
//Java Code to create singleton class
// With Lazy initialization
public class GFG
{
// private instance, so that it can be
// accessed by only by getInstance() method
private static GFG instance;
private GFG()
{
// private constructor
}
//method to return instance of class
public static GFG getInstance()
{
if (instance == null)
{
// if instance is null, initialize
instance = new GFG();
}
return instance;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Pros:
Object is created only if it is needed. It may overcome resource overcome and wastage of CPU time. Exception handling is also possible in method. Cons:
Every time a condition of null has to be checked. instance can’t be accessed directly. In multithreaded environment, it may break singleton property.
Thread Safe Singleton:
// Java program to create Thread Safe
// Singleton class
public class GFG
{
// private instance, so that it can be
// accessed by only by getInstance() method
private static GFG instance;
private GFG()
{
// private constructor
}
//synchronized method to control simultaneous access
synchronized public static GFG getInstance()
{
if (instance == null)
{
// if instance is null, initialize
instance = new GFG();
}
return instance;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Pros:
Lazy initialization is possible. It is also thread safe. Cons:
getInstance() method is synchronized so it causes slow performance as multiple threads can’t access it simultaneously.
Lazy initialization with Double check locking:
// Java code to explain double check locking
public class GFG
{
// private instance, so that it can be
// accessed by only by getInstance() method
private static GFG instance;
private GFG()
{
// private constructor
}
public static GFG getInstance()
{
if (instance == null)
{
//synchronized block to remove overhead
synchronized (GFG.class)
{
if(instance==null)
{
// if instance is null, initialize
instance = new GFG();
}
}
}
return instance;
}
}
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
27
28
29
30
Pros:
Lazy initialization is possible. It is also thread safe. Performance reduced because of synchronized keyword is overcome. Cons:
First time, it can affect performance.
Bill Pugh Singleton Implementation:
// Java code for Bill Pugh Singleton Implementaion
public class GFG
{
private GFG()
{
// private constructor
}
// Inner class to provide instance of class
private static class BillPughSingleton
{
private static final GFG INSTANCE = new GFG();
}
public static GFG getInstance()
{
return BillPughSingleton.INSTANCE;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
When to use What
- Eager initialization is easy to implement but it may cause resource and CPU time wastage. Use it only if cost of initializing a class is less in terms of resources or your program will always need the instance of class.
- By using Static block in Eager initialization we can provide exception handling and also can control over instance.
- Using synchronized we can create singleton class in multi-threading environment also but it can cause slow performance, so we can use Double check locking mechanism.
- Bill Pugh implementation is most widely used approach for singleton classes. Most developers prefer it because of its simplicity and advantages.