你的单例足够单吗

原创 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
  • 240

如何写出正确的单例模式

本文转载自http://wuchong.me/blog/2014/08/28/how-to-correctly-write-singleton-pattern/#comments 有关单例模式的文章...
  • Samuel__Liu
  • Samuel__Liu
  • 2016年10月23日 23:07
  • 796

单例模式及销毁

通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例。 单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。 从具体...
  • p2016
  • p2016
  • 2017年06月10日 17:39
  • 452

为什么要用单例模式?

我们在编程中最常用的模式就是单例模式了,然而单例模式都用在什么场合?为什么不用静态方法而要用单例模式呢?要搞清这些问题,需要从静态方法和非静态方法的区别和联系说起。   一、静态方法常驻内...
  • jiary5201314
  • jiary5201314
  • 2016年09月22日 22:30
  • 1134

彻底构造一个安全的单例模式

正常情况下构造单例模式主要分为两种,饿汉和懒汉,即懒加载(延迟加载)和直接加载。饿汉方式如下:public class Singleton{ private static final Sing...
  • kid_2412
  • kid_2412
  • 2016年11月30日 10:11
  • 583

集群环境中的单例设计模式

何时使用(单例模式):         在创建线程池、缓存等对象时,我们可以使用单例模式来避免资源的浪费。但是如果你想要存储比如产品价格等全局数据的时候,单例模式就成了一种反面模式,要考虑用其他方法...
  • defonds
  • defonds
  • 2013年10月14日 10:55
  • 5991

单例对象的并发调用需要同步

为什么单例对象的并发调用需要同步?最近在阅读 《Inside theJVM》 这本书,结合一些日常工作学习中的感想,随便写一些东西,蜻蜓点水,不必有章法。 关于“单例同步”: 一直有人在问单例...
  • paincupid
  • paincupid
  • 2016年07月02日 16:12
  • 1319

单例模式和工厂模式

http://detail.tmall.com/item.htm?spm=a220m.1000858.1000725.6.lZNUC4&id=18800856374&_u=1nmsbjv7aa5&ar...
  • fangleijiang
  • fangleijiang
  • 2014年02月25日 15:00
  • 9572

如何正确的使用单例

关于单例getInstance()传入参数的讨论
  • woyaowenzi
  • woyaowenzi
  • 2015年02月25日 01:03
  • 2970

单例模式的七种写法以及注意事项

第一种(懒汉,线程不安全):   Java代码   public class Singleton {      private static Singleton instance...
  • yawinstake
  • yawinstake
  • 2017年01月16日 22:43
  • 513
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:你的单例足够单吗
举报原因:
原因补充:

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