设计模式--单例模式

单例模式: 在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。

一、饿汉式

7种单例设计模式

饿汉式的关键在于instance作为类变量直接得到初始化,该方法能够百分之百的保证同步,也就是说instance在多线程下也不可能被实例化两次,但是instance被ClassLoader加载后可能很长时间才会被使用,那就意味着instance实例所开辟的空间的堆内存会驻留更久的时间

如果一个类中的成员属性比较少,所占用的内存资源不多,饿汉式也未尝不可。总结起来,饿汉式可以保证多线程下唯一的实例,getInstance性能也比较高,但是无法进行懒加载

二、懒汉式(不可用于多线程,不可取)

7种单例设计模式

Singleton2 的类变量instance = null,当Singleton2.class被初始化的时候instance并不会被实例化,在getInstance方法中会判断instance 实例是否被实例化,看起来没什么问题,但在多线程环境下,会导致instance可能被实例化多次。 线程1判断null == instance为true时,还没有实例化instance,切换到了线程2运行,线程2判断null == instance也为true。就会实例化多次。

三、懒汉式 + 同步方法(性能低,不可取)

7种单例设计模式

 

采用懒汉式 + 数据同步方式既满足了懒加载又能百分之百保证instance实例的唯一性,但是synchronized 关键字天生的排他性导致了getInstance方法只能在同一时刻被一个线程所访问,性能低下

四、Double-Check(性能不错,但是有可能发生重进入)

7种单例设计模式

 

当两个线程发现null == instance成立时,只有一个线程有资格进入同步代码块,完成对instance的实例化,随后的线程发现 null == instance 不成立则无须进行任何操作,以后对getInstance的访问就不需要数据同步的保护了。

这种方式看起来那么的完美,既满足了懒加载,有保证instance实例的唯一性。Double-Check的方式提供了高效的数据同步策略,可以允许多个线程同时对getInstance进行访问。但是这种方式有可能引起空指针异常,我们分析一下。

Singleton4的构造函数中,初始化了conn还有Singleton4自身,根据JVM指令重排序和Happens-Before规则,这两者之间的实例化顺序并无前后关系的约束,那么极有可能instance最先被实例化,而conn并未完成实例化,未完成初始化的实例调用其他方法将会抛出空指针异常。

五、Volatile + Double + Check(懒加载,优,可取)

7种单例设计模式

 

在instance前 加上 volatile的关键字,则可以防止重排序的发生。

六、Holder 方式(跟5的原理一样,但是代码简洁,可取)

7种单例设计模式

 

在Singleton6中并没有instance的静态变量,而是将其放在静态内部类Holder类中,因此Singleton6初始化过程中并不会创建Singleton6的实例,Holder类中定义了Singleton6的静态变量,并且直接进行了实例化,当Holder被直接饮用的时候则会创建Singleton6的实例,该方法又是同步方法,保证了内存的可见性,JVM的顺序性和原子性。Holder方式是单例设计最好的设计之一。

七、枚举方式(最优,强烈推荐)

7种单例设计模式

 

枚举类型不允许被继承,同样是线程安全且只能被实例化一次,但是枚举不能够懒加载,对于Singleton6主动使用,比如调用其中静态方法则INSTANCE会立即得到实例化。

也可以对其进行改造,增加懒加载的特性。类似于Holder。

7种单例设计模式

##################### ps:

此文章转载于:今日头条的某个大神:https://www.toutiao.com/a6628523839120736771/?tt_from=weixin&utm_campaign=client_share&wxshare_count=1&timestamp=1544368831&app=news_article&utm_source=weixin&iid=53381483377&utm_medium=toutiao_android&group_id=6628523839120736771

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值