单例安全性
# 实现模式
(转自维基百科)
实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。
实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。
单例模式在多线程的应用场合下必须小心使用。如果当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例,这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。 解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(虽然这样会降低效率)。
# 单例安全性
由于保证单例唯一性,引进互斥锁导致效率的问题,其实存在某种良好的解决办法的。
综上所述,对于单例模式,其具体的程序实现(方案)要点概括如下:对于单例模式,其具体的程序实现(方案)要点概括如下:1 单例对象延迟加载(构造),。即使用的时候(获取时)才给予申请构造。
在此,我想说更多的是“双重检测”技术,保证单例对象的多线程访问安全性。
# 示例说明
去年,项目组的周会讨论过,关于创建单件模式的安全性问题。那时候,我‘引荐’了“双重检测”该方法,同时提到Loki类库实现单例模式的做法。当时,大家却表现“未曾相识”的感觉,所以我那天晚上发了一段解释到项目组的邮件群。如下:
……
之前的周会讨论过,关于创建单件模式的安全性问题。大家是否还有印象? **同学应该还有印象的吧,呵呵!
好像大家对此了解不多,所以我晚上在家里翻出了Loki老代码查看对照了下,在此稍微总结下,和大家一起分享和讨论。
Loki泛型类库实现单件,使用的是“双检测”单件对象,保证创建安全。见图说明:
btw:
Loki -- http://loki-lib.sourceforge.net/
附件 -- Loki单件的实现。
至于Loki类库是什么,大家可以google下就知道了!
先描述这么多吧,有情况再讨论。
--
(完)
没有评论:
发表评论