您的位置:首页 > 其它

多线程Singleton单件模式

2009-12-07 11:45 197 查看
Singleton模式是最简单的模式,比较汗颜的是自己一直以来使用的是单线程的Singleton模式,最近在听了李建忠老师的模式讲座录像后,才发现自己一直没注意到这点。这个录像讲座在后面给出了链接地址: C#面向对象设计模式纵横谈(2):Singleton 单件(创建型模式)

下面内容整理自李建忠老师的讲课内容:

单线程的Singleton模式

public class Singleton
{
private static Singleton instance;

private Singleton() { }

public static Singleton Instance
{
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
}

要点:

Singleton模式中的实例构造器可以设置为protected以允许子类派生。
Singleton模式一般不要支持ICloneable接口,因为这可能会导致多个对象实例,与Singleton模式的初衷违背。
Singleton模式一般不要支持序列化,因为这也有可能导致多个对象实例,同样跟Singleton模式的初衷违背。
Singleton模式只考虑到了对象创建的管理,并没有考虑对象销毁的管理。就支持垃圾回收的平台和对象的开销来讲,我们一般没必要对其销毁进行特殊的管理。
上述代码不支持多线程环境,上述代码在多线程下,仍然有可能得到Singleton类的多个实例。

多线程的Singleton模式

public class Singleton
{
private static volatile Singleton instance = null;

private static object lockHelper = new object();

private Singleton() { }

public static Singleton Instance
{
get
{
if (instance == null)
{
lock (lockHelper)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
}

代码说明:

volatile C#关键字作用,简单来说,编译器编译我们的代码时候,会对代码作一些优化,进而对代码进行了微调,使用volatile关键字就可以避免这个微调。继而严格意义上保证不会产生多线程。更详细的关于volatile 的说明,请看参考资料。
双检查加锁模式。在lock之外和之内,我们做了instance是否为空的检查。这叫双检查。因为同步控制的时间太长了。双检查能够最高效地实现多线程安全的访问。

使用.net特有的支持多线程的单件模式代码

public sealed class Singleton
{
public static readonly Singleton Instance = new Singleton();
private Singleton() { }
}

代码说明:

sealed 修饰符表示该类是密封类,不能被继承。你可以按需修改。
这里readonly关键字只是不希望客户程序将Instance字段设置为null等不合理的值。
*** static *** = new Singleton(); 是使用了内联初始化技术,这部分初始化其实是在static Singleton()中执行的。即上面的代码相当于:
public sealed class Singleton
{
public static readonly Singleton Instance;
static Singleton()
{
Instance = new Singleton();
}
private Singleton() { }
}

上述代码在编译时,会使用一个名为beforefieldinit元数据标志。此标志使得运行库能够在任何时候执行类型构造函数方法,只要该方法在第一次访问该类型的静态字段之前执行即可。换句话说,beforefieldinit 为运行库提供了一个执行主动优化的许可。如果没有 beforefieldinit,运行库就必须在某个精确时间运行类型构造函数,即,恰好在第一次访问该类型的静态或实例字段和方法之前。
静态构造器自身就可以保证,多线程情况下,系统就可以保证只有一个执行。

缺点:

不支持参数化单件构造器。即静态构造器不支持参数,就导致我们无法利用静态构造器实现传参数的单件。

参考资料:

讲讲volatile的作用
http://blog.21ic.com/user1/2949/archives/2007/35599.html

Implementing the Singleton Pattern in C#
http://www.yoda.arachsys.com/csharp/singleton.html

初始化内联引用类型静态字段
http://msdn.microsoft.com/zh-cn/library/ms182275.aspx

通过七个关键编程技巧得益于静态内容
http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/us0501StaticsinNET.mspx?mfr=true

模式设计c#--创建型--Singleton
http://www.cppblog.com/mzty/archive/2006/01/03/2384.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: