单例模式

幻昼 2020年06月04日 292次浏览

单例模式是什么?

确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

单例模式好处

通常使用单例对象都是重量级,里面有很多对象,例如线程池、缓存系统、网络请求等等,很耗资源。使用单例不用重复创建这种对象,其它地方也可以重复使用这个对象,提高性能。

单例模式特征

  1. 构造方法不对外开发的,一般是private
  2. 通过一个静态方法或者枚举返回单例类的对象
  3. 注意多线程的场景
  4. 注意单例类对象在反序列化时不会重新创建对象

单例模式分类

1. 懒汉式单例

// 懒汉单例,第一次调用时实例化自己
    static class Singleton1 {

        // 私有的静态变量
        private static Singleton1 mInstance = null;

        private Singleton1() {
            System.out.println("懒汉式单例");
        }
	// 此时线程不安全,可加synchronize
        public static Singleton1 getInstance() {
            if (mInstance == null) {
                mInstance = new Singleton1();
            }
            return mInstance;
        }
    }

2. 饥汉式单例

    static class Singleton2 {
        private static Singleton2 sInstance = new Singleton2();

        private Singleton2() {
        }

        public static Singleton2 getInstance() {
            return sInstance;
        }
    }

3. 双重检验,DCL

//双重校验,DCL
    static class Singleton3 {

        // 私有的静态变量
        private volatile static Singleton3 mInstance = null;

        private Singleton3() {
            System.out.println("DCL单例");
        }

        // 线程安全
        public static Singleton3 getInstance() {
            if (mInstance == null) {
                synchronized (Singleton3.class) {
                    if (mInstance == null) {
                        mInstance = new Singleton3();
                    }
                }
            }
            return mInstance;
        }
    }

4. 静态内部类单例

//静态内部类单例
    static class Singleton4 {
        private Singleton4() {
        }
        private static class Holder{
            private static final Singleton4 INSTANCE = new Singleton4();
        }

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

5. 枚举单例

static enum Singleton5 {
        INSTANCE;
    }

6.容器类单例

static class SingletonManager{
        private static Map<String, Object> objectMap = new HashMap<>();

        public static void registerService(String key, Object instance) {
            if (!objectMap.containsKey(key)) {
                objectMap.put(key, instance);
            }
        }

        public static Object gerService(String key) {
            return objectMap.get(key);
        }
    }