你的单例足够单吗

原创 2007年05月11日 09:41:00
什么是单例:
单例模式(Singleton)是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。[wikipedia]
Delphi 源码中的单例应用:
var
  FClipboard: TClipboard;

function Clipboard: TClipboard;
begin
  
if FClipboard = nil then
    FClipboard := TClipboard.Create;
  Result := FClipboard;
end;



问题的提出:
上述代码不是线程安全的。假设 A 率先调用函数 Clipboard,局部变量 FClipboard会先进行实例化。在实例尚未完全创建完之前,如果 B 也尝试调用函数Clipboard,那么它也会去对 FClipboard 进行实例化。因为变量FClipboard此时依然为空指针。于是乎AB分别创建了一个 TClipboard 的实例,单例不再单!其中的一个并且变成了一个内存泄漏。这种泄漏往往发送在构建函数需要耗费较长时间的情况下。如何将上述代码改成线程安全的呢?其实可以通过加入临界区处理来解决

var
 
FClipboard: TClipboard;
  GClipboardLocker: TRTLCriticalSection;

function Clipboard: TClipboard;
begin
  if FClipboard = nil then
  begin

   EnterCriticalSection(GClipboardLocker);
   
try
     
if FClipboard = nil then
       FClipboard := TClipboard.Create;
   
finally
     LeaveCriticalSection(GClipboardLocker);
   
end;
 end
;
  Result := FClipboard ;
end;

initialization
  InitializeCriticalSection(GClipboardLocker);
finalization
  DeleteCriticalSection(GClipboardLocker);
end. 

 

小结:
单例模式简约而不简单,当开发往多线程延伸之后,可能还会爆出更多的问题。单例就是一个全局变量,建议不要滥用,否则软件的层次结构会被破坏。

这个单例足够单

单例模式的作用是用来解决一个应用中某个类只有唯一一个对象的问题。单例类在iOS开发中是非常重要的,在系统提供个类中,诸如:UIApplication类、NSUserDefaults类、NSNotifi...
  • qq_22157341
  • qq_22157341
  • 2017-02-15 15:43:37
  • 263

做移动互联网App,你的测试用例足够吗?

  • 2011年11月22日 17:44
  • 158KB
  • 下载

你真的会写Java单例么?

java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。   单例模式有一下特点:   1、单例类只能有一个实例。   2、单例类必须自己自己创建自己的唯一实例...
  • Jo__yang
  • Jo__yang
  • 2016-08-04 20:28:20
  • 1228

你真的会写单例吗?

单例的正确姿势 Java单例模式可能是最简单也是最常用的设计模式,一个完美的单例需要做到哪些事呢? 单例(这不是废话吗)延迟加载线程安全没有性能问题防止序列化产生新对象防止反射攻击 可以看到,真正要...
  • u014610664
  • u014610664
  • 2016-07-02 10:16:08
  • 10243

cmd访问被拒绝,因为您没有足够的特权

是权限不够的原因 开始——程序——附件 右键“命令提示符”以管理员身份运行,然后在输入上面命令就行了...
  • mnonm_mnonm_mnonm
  • mnonm_mnonm_mnonm
  • 2013-01-15 13:07:16
  • 10288

您没有足够的权限访问连接的属性。 请与管理员联系

症状:在 Service Pack 1 (SP 1) 或 Microsoft Windows XP Service Pack 2 (SP 2)使用的 Microsoft Windows Server ...
  • solarium
  • solarium
  • 2009-02-05 10:34:00
  • 19965

Win10下执行mklink提示你没有足够权限执行此操作

创建 symlink 需要有“SeCreateSymbolicLinkPrivilege”用户权利,administrators 组成员默认具有此权利。 这个权利可以在“本地安全策略(secpol.m...
  • u011583025
  • u011583025
  • 2016-10-24 08:23:02
  • 6896

IOS中单例怎么销毁,会造成内存泄露吗?

官方文档中是这么解释的:  " When an application terminates, objects may not be sent a dealloc message since the...
  • u010158696
  • u010158696
  • 2016-07-02 13:01:42
  • 2007

单例模式学习及几种不同写法

单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。要实现这一点,可以从客户端对其进行实例化开始。因此需要用一种只允许生成对象类的唯一实例的机制,“阻止”所有想...
  • yueaini10000
  • yueaini10000
  • 2016-06-24 09:33:23
  • 538

浅谈使用单元素的枚举类型实现单例模式

简介 使用单元素的枚举实现单例模式简介通常情况下,我们写单例模式的时候无非就是三个步骤:构造器私有化,声明私有静态变量,提供静态获取实例的方法。简单说就是以下这种方式:class SingletonA...
  • huangyuan_xuan
  • huangyuan_xuan
  • 2016-08-12 22:47:52
  • 6296
收藏助手
不良信息举报
您举报文章:你的单例足够单吗
举报原因:
原因补充:

(最多只允许输入30个字)