guguoyi / shareber

7 stars 0 forks source link

2018-11-30[Eric Wang] Singleton #1

Open sunrisenew opened 5 years ago

sunrisenew commented 5 years ago

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
    }

}
2735551038 commented 5 years ago

https://www.callicoder.com/java-singleton-design-pattern-example/