单例模式详解

         java中单例模式定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供。”
        简单的来说,单例模式就是保证全局中某个指定类只有一个实例对象。嗯,举个简单的例子,可以理解为一个锁只能有一把钥匙,无论这把钥匙在谁手上在什么地方,使用多少次,只能有一把。绝对不能再被new一把出来。
        明白这个中心主旨后,看代码就更容易理解设计思路了。
        
        常规单例模式总的来说也就那么几种:
        1.懒汉式。
               
            先看一段简单的代码:
                
            详细说明下(大神绕道):
           首先通过将构造函数私有,确保SingleTon类不会被直接new出来,那就得提供一个公共的获取方法才行,getInstance()是一个统一获取的方法。接着看这个方法,先进行一个if的判断,确定singleTon是否被实例化过。如果没有,就new一个;否则直接跳过,这样就保证了通过getInstance()获取的对象始终保证是同一个。
         上面的例子就是懒汉式的,只当你调用getInstance()方法时,才会new;不调用,就没我的事,所以俗称懒汉式,典型的时间换空间。
        但是能这样执行的前提是非多线程的情况下,如果存在多线程,那就可能会多个对象了。
        假设现在存在线程A和线程B,线程嘛,执行权随机的。看下面这种情况:当A线程刚通过第14行的if判断,还没有执行new操作时,执行权被B线程获得,接着B线程执行完getInsance()方法,new了一个SingleTon实例对象。此时执行权又被A线程获得,接下来又new了一个SingleTon对象。这样就违背了单例设计的初衷了。
        这时候我们是不是要考虑怎样才能让所有的线程获取到的都是同一个对象呢?很容易就想到了线程锁,所以代码稍作修改:
      
        再回到上面那个例子,如果线程A刚通过第16行的if判断,还未执行new的操作。cpu执行权被线程B获得,执行到第14行时,由于synchronized的存在,只能等待锁里A线程执行完。当B再次执行时,会进行第二次的if判断,此时singleTon已被new过,跳出if。这样就保证了getInstance()方法获取对象的唯一性,这种模式称为双重检查锁。
         细心的哥们可能会发现,就算没有最外层的if判断,也能达到多线程只new一个的效果。但是此时会出现这样一种情况:无论singleTon    是否为 null,都会执行synchronized的判断,而这样的判断是很耗资源的。所以加上外面的一层if判断,效率就大为提高。
             
        2.饿汉式。
        
                饿汉式,顾名思义,饿了肯定要主动出击的,所以饿汉式里的SingleTon是主动的new的,不管你是否调用getInstance()方法,它会提前new好。这种方法非常简单,因为单例的实例被声明成了static和final变量了,在第一次加载到内存中就会初始化,所以饿汉式是线程安全的,不会重复的创建,不存在懒汉式的多线程不安全问题。但如果这个方法是完美的,那就没必要说那么久的双检锁了。饿汉式是典型的属于空间换时间。
        3.静态内部类。
        
        这种方式也是《Effective Java》上所推荐的。这种方式使用JVM本身机制保证了线程安全问题,由于SingleTonHolder是私有的,除了通过getInstance()之外没有其它方法可以访问到,所以有懒汉式的特点。同时读取实例时不会同步,没有性能上的缺陷,也是个人比较推崇的。
        4.枚举。
        
       借用一下: 使用enum关键字来实现单例模式的好处是这样非常简洁,并且无偿地提供了序列化机制,绝对防止多次实例化,即使是在面对复杂的序列化或者反射攻击的时候。——来自《Effective Java》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值