Singleton design pattern appreciated

Definitions: Ensure a class has only one instance, and provide a global point of access to it (to ensure that only one instance of a particular class, and to instantiate the instance to provide the entire system).

1. hungry Chinese-style

public class Singleton {

    private static final Singleton INSTANCE = new Singleton();

    private Singleton(){}

    public static Singleton getInstance(){
        return INSTANCE;
    }

    public void method(){
        System.out.println("普通方法");
    }

    public static void main(String[] args) {
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2);
    }
}

In this way the work of the most commonly used simple. After the class is loaded into memory, will only be instantiated once, it will only produce one instance, JVM thread-safe. The only drawback is that regardless of the use or not, will be completed when the class is instantiated loaded.

2. lazy style

public class SingletonLazy {

    private static volatile SingletonLazy INSTANCE;

    private SingletonLazy(){}

    public static SingletonLazy getInstance(){
        if (INSTANCE == null){
            synchronized (Singleton.class){
                if (INSTANCE == null){
                    INSTANCE = new SingletonLazy();
                }
            }
        }
        return INSTANCE;
    }

    public void method(){
        System.out.println("普通方法");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            SingletonLazy instance = SingletonLazy.getInstance();
            new Thread(()-> System.out.println(instance.hashCode())).start();
        }
    }
}

Although in this way to achieve the purpose of on-demand initialized, but poses a problem not thread-safe, so the solution by locking way, but it is problematic efficiency drops, the other variables need to add the volatile keyword, to prevent the re-instruction Sort.

3. static inner classes

public class SingletonInner {

    private SingletonInner(){}

    private static class SingletonInnerHolder{
        private static final SingletonInner INSTANCE = new SingletonInner();
    }

    public static SingletonInner getInstance(){
        return SingletonInnerHolder.INSTANCE;
    }

    public void method(){
        System.out.println("普通方法");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            SingletonInner instance = SingletonInner.getInstance();
            new Thread(()-> System.out.println(instance.hashCode())).start();
        }
    }
}

This way to solve the problem in two ways above, when SingletonInner class is loaded, SingletonInnerHolder inner classes will not be loaded, only calling getInstance () time will be loaded, both reached the lazy loading, and to ensure that only one instance.

4. enumerating

public enum  SingletonEnum {

    INSTANCE;

    public void method(){
        System.out.println("普通方法");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(()->              System.out.println(SingletonEnum.INSTANCE.hashCode())).start();
        }
    }
}

This way not only can solve the problem of thread synchronization, but also to prevent de-serialization, because there is no enumeration class constructor.

 

Guess you like

Origin www.linuxidc.com/Linux/2020-03/162734.htm