When Singleton is not Singleton?
Singleton design pattern is quite a helpful design pattern that allows only one object of your class to be created and then reuse but common missteps can unintentionally allow more than one instance to be created. In this article we’ll see that how it can occur and how to prevent it.
Multiple Singleton objects created through deserialization of serialized version
The easiest way to avoid all these issue is to use an enum instead:
public enum MyUtils {
INSTANCE;
public void doSomething() {
// impl.
}
}
Then the following to call the method:
MyUtils.INSTANCE. doSomething();
In the synchronized scenario, what about to put a double check instead a synchronized method, like this:
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
So we still avoid the concurrent scenario, because only one you will initialize the variable, even if another thread enters the synchronized block and the method has less performance issues, because multiple threads can access it at the same time.
Multiple Singleton objects created through deserialization of serialized version
- Multiple singletons arriving due to somebody has derived a subclass from singleton class
- Multiple objects of the same singleton class due to Improper Synchronization
- Multiple objects still be created if you add a synchronized block to the constructor call.
- Singleton Class Destroyed by GC, then Re-loaded
- Multiple Singletons Loaded Concurrently by Multiple Class Loaders
- Multiple Singletons in more than One Java Virtual Machine
The easiest way to avoid all these issue is to use an enum instead:
public enum MyUtils {
INSTANCE;
public void doSomething() {
// impl.
}
}
Then the following to call the method:
MyUtils.INSTANCE. doSomething();
In the synchronized scenario, what about to put a double check instead a synchronized method, like this:
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
So we still avoid the concurrent scenario, because only one you will initialize the variable, even if another thread enters the synchronized block and the method has less performance issues, because multiple threads can access it at the same time.