单例设计模式

必须满足以下条件:
1、某个类只能有一个实例
构造器私有化
2、必须自行创建这个实例
静态变量来保存这个唯一的实例
3、必须自行向整个系统提供这个实例
对外提供获取该实例对象的方式:1.直接暴露2.静态变量的get方法获取

几种常见形式:
饿汉式:在类初始化时直接创建对象,不存在线程安全问题,不管你是否需要都会去创建
1、直接实例化饿汉式(简洁直观)

public class Singleton1 {
    public static final Singleton1 INSTANCE = new Singleton1();
    private Singleton1(){

    }
}

2、枚举式(最简洁)

public enum Singleton2 {
    INSTANCE
}

3、静态代码块饿汉式(适合复杂实例化)

public class Singleton3 {
    public static final Singleton3 INSTANCE;
    static {
        INSTANCE = new Singleton3();
    }
    private Singleton3(){

    }
}

懒汉式:延迟创建这个实例对象
1、线程不安全(适用于单线程)

public class Singleton4 {
    private static Singleton4 instance;
    private Singleton4(){

    }
    public static Singleton4 getInstance(){
        if(instance == null){
            instance = new Singleton4();
        }
        return instance;
    }
}

2、线程安全(适用于多线程)

public class Singleton5 {
    private static Singleton5 instance;

    private Singleton5() {

    }
    public static Singleton5 getInstance() {
        if (instance == null) {
            synchronized (Singleton5.class) {
                if (instance == null) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    instance = new Singleton5();
                }
            }
        }
        return instance;
    }
}

3、静态内部类形式(适用于多线程)

/*
* 在内部类被加载和初始化时,才创建INSTANCE实例对象
* 静态内部类不会自动随着外部类的加载和初始化而初始化,它是要单独去加载和初始化的
* 因为实在内部类加载和初始化时创建的,因此是线程安全的
 */
public class Singleton6 {
    private Singleton6() {

    }

    private static class Inner {
        private static final Singleton6 INSTANCE = new Singleton6();
    }

    public static Singleton6 getInstance() {
        return Inner.INSTANCE;
    }
}

总结:看需求选择使用饿汉式还是懒汉式,如果选择饿汉式的话枚举式是最简洁的,懒汉式则是静态内部类形式最简洁