单例模式

228 阅读1分钟
/**
 * 单例模式
 * 个人理解:1.单例模式常说的有五种:饿汉式、懒汉式、双重检查、静态内部类、枚举,单线程下都可以实现单例模式。
 *  2.多线程下双重检查(通过成员变量volatile+synchronized实现,但是效率相对会低)、
 *  静态内部类(静态资源只加载一次)、
 *  枚举(枚举类在编译时候底层还是class,元素是final static修饰,且每个值在static代码块中调用一次构造函数)线程安全。
 *  3.对于枚举方式还可以防止反射和序列化攻击(反射在通过newInstance创建对象时,会检查该类是否ENUM修饰,如果是则抛出异常,反射失败。)
 *
 */
public class SingletonDesignPattern {

    public static void main(String[] args) {
        Singleton4 singleton = Singleton4.getInstance();
        Singleton4 singleton1 = Singleton4.getInstance();
        System.out.println(singleton == singleton1);
    }
}

/**
 * 饿汉式
 */
class Singleton {

    private static Singleton singleton = new Singleton();

    private Singleton() {

    }

    public static Singleton getInstance() {
        return singleton;
    }
}

/**
 * 懒汉式
 */
class Singleton1 {

    private static Singleton1 singleton;

    private Singleton1() {

    }

    public static Singleton1 getInstance() {
        if (singleton == null) {
            singleton = new Singleton1();
        }
        return singleton;
    }
}

/**
 * 双重检测
 */
class Singleton2 {

    private static volatile Singleton2 singleton;

    private Singleton2() {

    }

    public static Singleton2 getInstance() {
        if (singleton == null) {
            synchronized (Singleton2.class) {
                if (singleton == null) {
                    singleton = new Singleton2();
                }
            }
        }
        return singleton;
    }
}

/**
 * 静态内部类
 */
class Singleton3 {

    private Singleton3() {

    }

    private static class SingletonInner {
        public static Singleton3 singleton = new Singleton3();
    }

    public static Singleton3 getInstance() {
        return SingletonInner.singleton;
    }
}

/**
 * 枚举类
 */
class Singleton4 {

    private Singleton4() {

    }

    enum SingletonEnum {
        INSTANCE;

        private Singleton4 singleton4;

        SingletonEnum() {
            singleton4 = new Singleton4();
        }

        public Singleton4 instance() {
            return singleton4;
        }

    }

    public static Singleton4 getInstance() {
        return SingletonEnum.INSTANCE.instance();
    }
}