• 设计模式(二)单例模式Singleton(创建型)


          几乎所有面向对象的程序中,总有一些类的对象需要是唯一的,例如,通过数据库句柄到数据库的连接是独占的。您希望在应用程序中共享数据库句柄,因为在保持连接打开或关闭时,它是一种开销。再如大家最经常用的IM,如QQ,在同一台电脑,一个帐号只能有唯一的登录。

    1. 问题

    怎样确保一个特殊类的实例是独一无二的(它是这个类的唯一实例),并且这个实例易于被访问呢?

    2. 解决方案

    1)全局变量:一个全局变量使得一个对象可以被访问,但它不能防止你实例化多个对象。因为你的任何代码都能修改全局变量,这将不可避免的引起更多调试的意外。换句话说,全局变量的状态总是会出现一些问题的。

    2)类构造函数私有和类自身的静态方法:让类自身负责保存它的唯一实例(静态变量)。这个类可以保证没有其他实例可以被创建(通过截取创建新对象的请求) ,并且它可以提供一个访问该实例的方法(静态方法)。这就是Singleton模式。

    3. 适用性
    在下面的情况下可以使用单件模式
    1)当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。

    2)当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

    4. 实现:

    单例模式的五种写法:
     1、懒汉
     2、恶汉
     3、静态内部类
     4、枚举
     5、双重校验锁
    一、懒汉,常用的写法
    class LazySingleton{
        private static LazySingleton singleton;
        private LazySingleton(){
        }
        public static LazySingleton getInstance(){
            if(singleton==null){
                singleton=new LazySingleton();
            }
            return singleton;
        }  
    }
    二、恶汉,缺点:没有达到lazy loading的效果
    class HungrySingleton{
        private static HungrySingleton singleton=new HungrySingleton();
        private HungrySingleton(){}
        public static HungrySingleton getInstance(){
            return singleton;
        }
    }
    三、静态内部类 优点:加载时不会初始化静态变量INSTANCE,因为没有主动使用,达到Lazy loading
    class InternalSingleton{
        private static class SingletonHolder{
            private final static  InternalSingleton INSTANCE=new InternalSingleton();
        }  
        private InternalSingleton(){}
        public static InternalSingleton getInstance(){
            return SingletonHolder.INSTANCE;
        }
    }
    四、枚举,《Effective Java》作者推荐使用的方法,优点:不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象
    enum EnumSingleton{
        INSTANCE;
        public void doSomeThing(){
        }
    }
    五、 双重校验锁,在当前的内存模型中无效
    class LockSingleton{
        private volatile static LockSingleton singleton;
        private LockSingleton(){}
        //详见:http://www.ibm.com/developerworks/cn/java/j-dcl.html
        public static LockSingleton getInstance(){
            if(singleton==null){
                synchronized(LockSingleton.class){
                    if(singleton==null){
                        singleton=new LockSingleton();
                    }
                }
            }
            return singleton;
        }
    }
     
  • 相关阅读:
    TSINGSEE青犀视频云边端架构产品EasyNVR/EasyGBS/EasyDSS区别及应用场景介绍
    【解决方案】TSINGSEE青犀视频云边端架构产品如何实现明厨亮灶汇总直播方案?
    【开发记录】RTSP/GB28181/Ehome协议安防视频服务平台EasyCVR使用golang orm操作数据库及基本使用步骤
    TSINGSEE青犀视频云边端架构产品是如何实现视频流传输的?
    【开发记录】安防视频上云服务云平台EasyCVR部署之docker部署步骤参考说明
    TSINGSEE青犀视频+海康合作研发RTMP推流摄像头出现无法推流或无法上线的情况如何配置?
    VC中利用管道技术取得DOS或者命令行以及外部程序的执行结果
    系统程序员成长计划拥抱变化(下)
    系统程序员成长计划Write once, run anywhere(WORA)(下)
    KJava虚拟机hack笔记编译
  • 原文地址:https://www.cnblogs.com/barrywxx/p/4399810.html
Copyright © 2020-2023  润新知