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关键字

    金麟岂能忍一世平凡 飞上了青天 天下还依然
  • 相关阅读:
    bzoj1934 Vote 善意的投票 最小割(最大匹配)
    poj3417 Network 树上差分+LCA
    bzoj1076 奖励关 期望dp
    bzoj1087 互不侵犯King 状压dp+bitset
    bzoj1041 圆上的整点 数学
    bzoj 1085骑士精神 迭代深搜
    CodeForces 1043D Mysterious Crime 区间合并
    2018.12.14 浪在ACM 集训队第九次测试赛
    2018.12.9 中国石油大学第四次新生训练赛题解
    2018.12.8 中国石油大学第三次新生训练赛题解
  • 原文地址:https://www.cnblogs.com/Auge/p/11536615.html
Copyright © 2011-2022 走看看