4. 单例模式
概念及定义
单例模式顾名思义:一个类在系统范围内只有一个实例。该类需要自己创建自己对应的唯一实例。当然这个实例不仅仅是存在于系统内部,还需要向其他实例提供访问自己的自己的入口。在 Spring 中因为容器的存在,大量使用了单例模式,减少了资源消耗。
单例模式的主要思想:
如果一个类在系统内使用的频率较高,则保证这个类在系统的生命周期内一直拥有唯一一个实例,减少该类在系统内频繁的创建与销毁对象,减少资源消耗。
单例模式中角色以及职责:
Singleton(单例角色类)
单例模式的实现类
单例模式的优缺点:
优点:
减少了高频访问类的对象的创建与销毁,减少资源消耗。
可以避免对资源的同时占用。
缺点:
单例模式没有抽象类,很难在 已有的类上进行扩展。
单例模式在一定程度上违反了单一职责原则。
实现步骤:
饿汉模式:在类加载的时候就创建对象,后续 getInstance 可以获取对象。
2.懒汉模式:在第一次调用 getInstance 的时候就创建对象,后续 getInstance 可以获取对象。
我们这边仔细分析一下代码:
仅仅靠 1 号注释处的操作,是否能保证单例模式的健壮性?
答案是否定的。
因为new LazySun()
并不是 atomic 操作。JVM 会会分成三步进行:
给对象分配内存。
调用构造方法创建对象。
返回对象引用。
因为存在指令重排机制,所以如果线程 1 先执行,且执行顺序为 132,在 3 执行结束而 2 还未执行的时机。这时候线程 2 进来了,这时候判断 lazySun 非空,而返回一个没有进行初始化的对象,这时候调用就会出现异常。
要解决这个问题就在 lazySun 变量上加上volatile
关键字,来禁止指令重排。
总结:
单例模式,从始至终通过 getInstance 获取的对象都是同一个。
单例模式有三个基本特征:
有且只有私有的构造方法。
拥有一个本类对象作为私有属性。
拥有一个 public static 方法,以提供对象的引用。
版权声明: 本文为 InfoQ 作者【下雨了】的原创文章。
原文链接:【http://xie.infoq.cn/article/a6ee379c710091f11472da3c8】。文章转载请联系作者。
评论