EagerSingleton
public class EagerSingleton {
private static volatile EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {
// private constructor
}
public static EagerSingleton getInstance() {
return instance;
}
}
Pros: Easy, thread safe
Cons: instance
may create before getInstance()
called.
When instance
load? instance
is a static variable, static varible will load when CLASS
load.
When CLASS
load? CLASS
only load when we use this CLASS (for example, CLASS.class
, CLASS.staticVariable
, CLASS.staticMethod
)
LazySingleton
public final class LazySingleton {
private static volatile LazySingleton instance = null;
private LazySingleton() {
// private constructor
}
public static LazySingleton getInstance() {
if (instance == null) {
synchronized (LazySingleton.class) {
instance = new LazySingleton();
}
}
return instance;
}
}
Pros: instance
only create when we call getInstance()
Cons: If 2 threads call get getInstance()
at same time and overcome if (instance == null)
condition. Then 2 threads will excute in order => 2 objects will be created
Double check LazySingleton
public class LazySingleton {
private static volatile LazySingleton instance = null;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (instance == null) { // first check
synchronized (LazySingleton.class) {
if (instance == null) { // second check
instance = new LazySingleton();
}
}
}
return instance;
}
Pros: instance
only create when we call getInstance()
and thread safe
Cons: Not yet
Why we need the // first check
? Currently, I think that check // first check
and return immediately is good for performace. If any time we getInstance()
we need to synchronized
, it may not good
Initialization on Demand Holder
public class Singleton {
private Singleton() {
}
private static class LazyHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}
Pros: instance
only create when we call getInstance()
and thread safe
Cons: If we want to pass to argument to getInstance(), I think we can not use this way