美文网首页
设计模式(23种)之单例模式

设计模式(23种)之单例模式

作者: 锦文豪武 | 来源:发表于2021-02-25 19:17 被阅读0次

    设计模式:是一套被反复使用、多数人知晓的、经过分类的、代码设计经验总结。就是一些开发套路,用于解决某一些特定场景的思想。
    aop:把通用的代码统一管理、动态代理、aspel等

    单例模式:
    保证整个程序中只有一个实例,常用的是特殊的类,比如管理类等。
    1、构造函数私有,防止在外部new对象,静态类也是一个单例
    2、内部必须提供一个静态的方法,让外部调用

    饿汉式,不好处是,应用启动的时候,类的加载就已经new了对象(不用)

       /**
       * 单例 ——饿汉式
       * 保证只有一个实例,私有化构造函数,防止外部被new 实例化
       */
     java:
    public class Singleton {
        private Singleton(){}
    
        private static Singleton instance =new Singleton();
    
        public static Singleton getInstance(){
            return instance;
        }
    }
    kotlin:
     class Singleton private constructor() {
              companion object{
                private val mInstance: Singleton = Singleton()
                fun getInstance(): Singleton{
                    return mInstance!!
              }
          }
    }
    

    懒汉式 只有在使用的时候才会new对象,可能更加高效,用的时候才会new

    问题:多线程并发的问题,线程不安全,如果有多线程还会存在多个实例。

    /**
     * 单例 ——懒汉
     * 只有在使用的时候才会new对象,可能更加高效,用的时候才会new
     */
    java:
    public class Singleton {
        private Singleton(){}
    
        private static Singleton instance ;
    
        public static Singleton getInstance(){
            if (null == instance){
                instance = new Singleton();
            }
            return instance;
        }
    }
    kotlin:
    class Singleton private constructor(){
        companion object{
            private var  mInstance: Singleton? = null
            fun getInstance(): Singleton{
                      if(null == mInstance){
                            mInstance = Singleton()
                     }
                return mInstance!!
            }
        }
    }
    

    解决懒汉式线程不安全,如果有多线程还会存在多个实例。添加synchronized 同步锁

    问题:每次获取都会判断同步锁,效率不高。

    /**
    *单例 ——懒汉
    */
    public class Singleton {
        private Singleton(){}
    
        private static Singleton instance ;
    
        public static synchronized Singleton getInstance(){
            if (null == instance){
                instance = new Singleton();
            }
            return instance;
        }
    }
    

    使用synchronized 同步锁,解决线程安全,但是效率不高问题。

    下面的既保证线程安全,效率也是比较高的。
    问题:但是又出现了一个问题:多线程会出现某一个线程改了共用对象(变量),短时间内另一个线程可能不可见的

    /**
    *单例 ——懒汉同步锁DCL
    */
    public class Singleton {
        private Singleton(){}
    
        private static Singleton instance ;
    
        public static  Singleton getInstance(){
            if (null == instance){
              //第一次判断同步锁
                synchronized(Singleton.class){
                    if (null == instance){
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    

    解决出现问题

    volatile关键字

    用处:

    1、防止重排序
    2、线程可见性:某一个线程改了共用对象(变量),短时间内另一个线程可能不可见的,因为每一个线程都有自己的缓存区。
    因为:实例化一个类对象,需要:
    1、开辟一个内存,
    2、初始化对象
    3、给变量赋值(指向内存地址)
    但是java多线程2和3的循环是不固定的,会出现
    1、开辟一个内存,
    2、给变量赋值(指向内存地址)
    3、初始化对象

    public class Singleton {
        private Singleton(){}
    
        private static volatile Singleton instance ;
    
        public static  Singleton getInstance(){
            if (null == instance){
              //第一次判断同步锁
                synchronized(Singleton.class){
                    if (null == instance){
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    

    静态内部类

    保证了线程安全,用到的时候才会进行实例化。

    /**
     * 静态内部类的形式
     * 既保证线程安全,又保证用的时候才会被实例化
     */
    public class Singleton {
        
        private Singleton(){}
        
        public static  Singleton getInstance(){
            return Singletons.instance;
        }
        private static class Singletons{
            private static  volatile Singleton instance ;
        }
    }
    

    单例模式——容器管理

    /**
     * 单例模式——容器管理,系统中用到
     */
    public class Singleton {
    
        private Singleton(){}
        private static Map<String,Object> singleMap= new HashMap<>();
        static {
            singleMap.put("singleMap",new Singleton());
        }
    
        public static Object getService(){
            return singleMap.get("singleMap");
        }
    }
    

    相关文章

      网友评论

          本文标题:设计模式(23种)之单例模式

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