zoukankan      html  css  js  c++  java
  • 设计优化之单例模式

    单例模式

    定义: 对象创建模式,确保系统中一个类只产生一个实例

    使用单例的好处:

    1): 对频繁使用的对象,省略创建对象所花费的时间

    2):new 操作次数的减少,对系统内存的使用频率也会降低,减轻GC压力,缩短GC停顿时间。

    创建单例模式

    第一种方式):类一加载就创建

    public class Singleton {
        /**
        私有化构造方法,外界不能通过new运算符创建对象
         */
        private Singleton(){
            System.out.println("create singleton");
        }
    
        /**
         * 实例化Singleton对象,static修饰,在类加载时实例化
         */
        private static Singleton instance = new Singleton();
    
        /**
         * 提供一个接口,外界可以通过该接口获取Singleton对象
         */
        public static Singleton getInstance(){
            return instance;
        }
    }
    

    弊端:在使用单例类时,不管有没有使用单例对象,单例变量都会通过new运算符实例化。

    public class Singleton {
        /**
        私有化构造方法,外界不能通过new运算符创建对象
         */
        private Singleton(){
            System.out.println("create singleton");
        }
    
        /**
         * 实例化Singleton对象,static修饰,在类加载时实例化
         */
        private static Singleton instance = new Singleton();
    
        /**
         * 提供一个接口,外界可以通过该接口获取Singleton对象
         */
        public static Singleton getInstance(){
            return instance;
        }
    
        public static void getString(){
            System.out.println("ceateString in Singleton");
        }
    }
    
    //执行Singleton.getString()程序输出
    create singleton
    ceateString in Singleton
    //不管有没有使用单例对象,单例变量都会通过new运算符实例化
    

    第二种方式):延迟加载

    先将单例变量声明为null,只有使用单例对象时,才通过new运算符创建实例

    public class LazySingleton {
        /**
        声明私有的构造器
         */
        private LazySingleton(){
            System.out.println("create lazySingleton");
        }
    
        /**
         * 单例变量初始化时不进行实例化
         */
        private static LazySingleton instance = null;
    
        /**
         * 1)提供获取单例对象的接口
         * 2)加锁:
         *   防止线程1在未赋值前,线程2可能判断instance == null,此时会产生两个单例对象
         * @return
         */
        public static synchronized LazySingleton getInstance(){
            if(instance == null){
                instance = new LazySingleton();
            }
            return instance;
        }
    }
    

    弊端:多线程调用时可能会产生两个单例对象,使用了sychonized可以预防该现象出现,但时耗远远大于第一种模式

    第三种方式):使用私有的静态成员内部类的方式

    public class StaticSingleton {
        /**
         * 将构造方法私有化
         */
        private StaticSingleton(){
            System.out.println("create staticSingleton");
        }
    
        /**
         * 创建静态成员内部类,在内部类中创建单例对象
         *  --:静态成员内部类在外部类加载时不会加载,只有在调用时才会加载
         */
        private static class SingletonHolder{
            private static StaticSingleton instance = new StaticSingleton();
        }
    
        /**
         * 提供获取单例的接口
         *  ---:满足了只有在使用单例时才使用new进行实例化,也不必使用synchonized关键字
         */
        public static StaticSingleton getInstance(){
            return SingletonHolder.instance;
        }
    
        public static void  get(){
            System.out.println("get");
        }
    }
    

    好处:解决了延迟加载的问题,单例可以在使用时创建,也不必使用synchonized关键字

    金麟岂能忍一世平凡 飞上了青天 天下还依然
  • 相关阅读:
    执行shell脚本的四种方式(转)
    linux free命令详解(一)
    linux TOP命令各参数详解【转载】
    grep命令
    vim常用命令
    IntelliJ Idea注释模板--类注释、方法注释
    [Chrome]抓请求直接生成可执行代码
    记录Markdown工具Typora
    VSCODE 配置远程开发环境
    [Boost::Polygon]多边形相减得到新的多边形序列
  • 原文地址:https://www.cnblogs.com/Auge/p/11536615.html
Copyright © 2011-2022 走看看