Open sunrisenew opened 5 years ago
class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton getInstance() { return INSTANCE; } }
class Singleton { private static volatile Singleton INSTANCE; private Singleton() {} public static synchronized Singleton getInstance() { if (INSTANCE == null) { INSTANCE = new Singleton(); } return INSTANCE; } }
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.
INSTANCE
null
@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(); } }
class Singleton { private Singleton() {} private static class InstanceHolder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return InstanceHolder.INSTANCE; } }
class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton() { if (INSTANCE != null) { throw new IllegalStateException(); } } public static Singleton getInstance() { return INSTANCE; } }
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 { INSTANCE; public void doSomething() { // Do Something } }
https://www.callicoder.com/java-singleton-design-pattern-example/
Singleton(Java)
Eager Singleton
Lazy Singleton
Lazy Singleton(Double Check)
If we use Java reflection to set
INSTANCE
withnull
, we can create another new instance.Lazy Singleton(Static Inner Class)
Against Reflection
Against Serizlization
Enum Singleton