2018-11-30[Eric Wang] Singleton
Opened this issue · 1 comments
sunrisenew commented
Singleton(Java)
Eager Singleton
class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
Lazy Singleton
class Singleton {
private static volatile Singleton INSTANCE;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
Lazy Singleton(Double Check)
class Singleton {
private static volatile Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null) { // #1
synchronized (Singleton.class) { // #2
if (INSTANCE == null) { // #3
INSTANCE = new Singleton(); // #4
}
}
}
return INSTANCE; // #5
}
}
If we use Java reflection to set INSTANCE
with null
, we can create another new instance.
@Test
public void testReflectSingleton() throws Exception {
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(() -> {
Singleton singleton = Singleton.getInstance();
try {
if (singleton != null) {
Class<Singleton> clazz = Singleton.class;
Field instanceField = clazz.getDeclaredField("INSTANCE");
instanceField.setAccessible(true);
instanceField.set(singleton, null);
singleton = Singleton.getInstance();
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(singleton);
});
thread.start();
}
}
Lazy Singleton(Static Inner Class)
class Singleton {
private Singleton() {}
private static class InstanceHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return InstanceHolder.INSTANCE;
}
}
Against Reflection
class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
if (INSTANCE != null) {
throw new IllegalStateException();
}
}
public static Singleton getInstance() {
return INSTANCE;
}
}
Against Serizlization
class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
if (INSTANCE != null) {
throw new IllegalStateException();
}
}
public static Singleton getInstance() {
return INSTANCE;
}
protected Object readResolve() {
return INSTANCE;
}
}
Enum Singleton
enum Singleton {
INSTANCE;
public void doSomething() {
// Do Something
}
}