【Dongle】【软考】【设计模式】单例模式

特点

  • 一个类只有一个实例对象
  • 一般用在管理共享的资源上,例如线性池、缓存、对话框、偏好设置、注册表、日志的对象,及充当打印机、显卡等设备的驱动程序的对象,等等

 

基本结构

  • 私有静态变量记录类的唯一实例
  • 私有构造器,只有类内才可以调用
  • 公共或保护型竞赛方法getInstance()实例化对象,提供全局访问点,并返回该对象

 

基本代码

Public class Singleton{
      private static Singleton uniqueInstance; //私有静态变量记录类的唯一实例
      private Singleton(){};    //私有构造器,只有类内才可以调用
      public static Singleton getInstance(){
           If(uniqueInstance==null){  //如果uniqueInstance为空,表示还没有实例化,实例化之后再返回
                  uniqueInstance=new Singleton();  //不存在就实例化,不需要永不实例化,即“延迟实例化”
            }
return uniqueInstance;  //表示已存在对象,返回该对象
      }
}

存在问题

       存在多线程的问题,即多个线程同时进入if判断,然后先后创建多个对象,利用synchronized(同步)解决

例如:

      public static synchronized Singleton getInstance(){}

       这样虽然避免了多个线程同时调用方法的问题,但是会产生另外一个比较严重的问题:就是每次调用这个方法的时候都需要同步,然而只有第一次执行这个方法才真正需要同步,故而每次都同步其实是一种累赘

那么该如何解决同步累赘问题呢?有三种方法:

       

       第一种,如果getInstance()的性能对应用程序不是很关键,就什么都别做。即不会产生同步影响的就不需要加synchronized了,因为同步一个方法可能会造成程序执行效率下降,故而当频繁调用getInstance()的时候,就需要考虑了。

       第二种,使用“急切”创建实例,而不用延迟到实例化的做法。如果应用程序中是创建并使用单例实例,或者在创建或运行时方面的负担不太繁重,你可能想要机器创建此单例,如:

Public classSingleton{
    privatestatic Singleton uniqueInstance=new Singleton();//静态初始化器创建实例,保证线程安全
    privateSingleton(){};   
    publicstatic Singleton getInstance()    {
        return uniqueInstance;  //已经有实例,直接使用它
    }
}

       即,在我需要使用实例之前就已经创建好了实例,使用时直接返回创建好的实例就OK

      第三种,用“双重检查加锁”,在getInstance()中减少使用同步。首先检查是否实例已经创建了,如果未创建,菜进行同步,这样一来,只有第一次会同步,正是我们想要的。

Public classSingleton{
    private volatile static Singleton uniqueInstance;  //volatile确保多个线程正确地处理uniqueInstance变量
    privateSingleton(){}; 
    publicstatic Singleton getInstance(){
        If(uniqueInstance==null){ //检查实例,如果不存在,就进入同步区块
            Synchronized(Singleton.class){ //只有第一次才彻底执行这里
                If(uniqueInstance==null){
                    uniqueInstance=new Singleton(); //进入区块后,再检查一次,如果仍是null,才创建实例
                }
            }
        }
        returnuniqueInstance;
    }
}

      如果性能是关心的重点,则双重锁的做法可以大大减少getInstance()的时间耗费。


 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 22
    评论
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值