美文网首页
单例模式

单例模式

作者: 枫中無声語 | 来源:发表于2017-08-30 17:18 被阅读0次

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

    单例模式的七种实现方式:

    1.饿汉式

    public class SingleInstance {
    
        private static SingleInstance mInstance = new SingleInstance();
        
        private SingleInstance() {}
        
        public static SingleInstance getInstance() {
            return mInstance;
        }
    }
    

    2.懒汉式--线程不安全

    public class SingleInstance {
    
        private static SingleInstance mInstance;
        
        private SingleInstance() {}
        
        public static SingleInstance getInstance() {
            if (mInstance == null) {
                mInstance = new SingleInstance();
            }
            return mInstance;
        }
    }
    

    3.懒汉式--线程安全

    public class SingleInstance {
    
        private static SingleInstance mInstance;
        
        private SingleInstance() {}
        
        public static synchronized SingleInstance getInstance() {
            if (mInstance == null) {
                mInstance = new SingleInstance();
            }
            return mInstance;
        }
    }
    

    优点:懒汉式的优点是只有在使用时才会被实例化,在一定程度上节约了资源;
    缺点:每次调用getInstance()都要同步,造成不必要的同步开销;

    4.Double Check Lock(DCL)双重校验锁,线程安全

    public class SingleInstance {
    
        private static SingleInstance mInstance;
        
        private SingleInstance() {}
        
        public static SingleInstance getInstance() {
            if (mInstance == null) {
                synchronized (SingleInstance.class) {
                    if (mInstance == null) {
                        mInstance = new SingleInstance();
                    }
                }
            }
            return mInstance;
        }
    }
    

    getInstance()方法中对mInstance进行了两次判空:
    第一层判断主要是为了避免不必要的同步;
    第二层判断是为了在null的情况下创建实例;
    优点:资源利用率高,第一次执行getInstance()的单例对象才会被实例化,效率高;
    缺点:第一次加载反应稍慢,由于Java内存模型的原因偶尔会失败。在高并发环境下也有一定的缺陷,虽然发生的概率很小;

    5.使用静态内部类的方式

    public class SingleInstance {
    
        private SingleInstance() {}
        
        /**
         * 静态内部类
         */
        private static class SingleInstanceHolder {
            private static SingleInstance mInstance = new SingleInstance();
        }
        
        public static SingleInstance getInstance() {
            return SingleInstanceHolder.mInstance;
        }
    }
    

    当第一次加载SingleInstance类时不会初始化mInstance,只有在第一次调用SingleInstancegetInstance()方法时才会导致mInstance被初始化。因此,第一次调用getInstance()方法会导致虚拟机加载SingleInstanceHolder类,这种方式不仅能保证线程安全,也能够保证单例对象的唯一性,同时也延迟了单例的实例化。

    6.枚举单例

    public enum SingleEnum {
        
        INSTANCE;
        
        public void doSomething() {
            System.out.println("do somth");
        }
    }
    

    在上述几种单例的实现方式中,如果将对象实例进行序列化,就会出现重新创建对象实例的情况。而对应枚举不会存在这个问题,因为即使反序列化它也不会重新生成新的实例。

    7.使用容器实现单例模式

    public class SingleManager {
    
        private static Map<String, Object> objMap = new HashMap<>();
        
        private SingleManager() {}
        
        public static void registerService(String key, Object instance) {
            if (!objMap.containsKey(instance)) {
                objMap.put(key, instance);
            }
        }
        
        public static Object getService(String key) {
            return objMap.get(key);
        }
    }
    

    在程序的初始,将多种单例类型注入到一个统一的管理类中,在使用是根据key获取对象对应的类型的对象。这中方式使得我们可以管理多种类型的单例,并且在使用时可以通过统一的接口进行获取操作,降低了用户的使用成本,也对用户隐藏了具体的实现,降低耦合度。

    相关文章

      网友评论

          本文标题:单例模式

          本文链接:https://www.haomeiwen.com/subject/benzdxtx.html