none
Singleton模式中的2个问题 RRS feed

  • 问题

  • 下面是MSDN上实现Singleton的一种方式,

    public sealed class Singleton
    {
    private static volatile Singleton instance;
    private static object syncRoot = new Object();
    private Singleton() {}
    public static Singleton Instance
    {
    get
    {
    if (instance == null)
    {
    lock (syncRoot)
    {
    if (instance == null)
    instance = new Singleton();
    }
    }
    return instance;
    }
    }
    }


    此方法确保了仅在需要实例时才会创建仅一个实例。此外,变量被声明为 volatile,以确保只有在实例变量分配完成后才能访问实例变量。
    最后,此方法使用 syncRoot 实例来进行锁定(而不是锁定类型本身),以避免发生死锁。



    我有2个问题:

    1.如果这里不用volatile,会发生什么问题?
    2.如果不锁定syncRoot对象,而是lock(this),会发生什么问题?“避免发生死锁”应该如何理解?


    they say nothing last forever
    2009年10月11日 12:52

答案

  • 第一个问题:
    编译器本身在编译的时候会对指令做一些微调,指令的执行顺序微调之后,即使你使用Lock了,还有可能会出现问题。
    但加上 volatile 关键字后将不会重新调整指令,严格按照指令顺序执行。
    声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制

    第二个问题:
    在静态属性中,不能访问this指针。

    Do My Best
    • 已标记为答案 KeFang Chen 2009年10月12日 3:55
    2009年10月12日 0:52
  • 1 volatile 在目前的版本毫无意义  但是为了可能出现的将来的编译器优化  还是加上吧

    2  static 上下文  不存在this.

    恭喜自己5星用户达成
    • 已标记为答案 KeFang Chen 2009年10月12日 3:55
    2009年10月12日 2:05
    版主

全部回复

  • 第一个问题:
    编译器本身在编译的时候会对指令做一些微调,指令的执行顺序微调之后,即使你使用Lock了,还有可能会出现问题。
    但加上 volatile 关键字后将不会重新调整指令,严格按照指令顺序执行。
    声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制

    第二个问题:
    在静态属性中,不能访问this指针。

    Do My Best
    • 已标记为答案 KeFang Chen 2009年10月12日 3:55
    2009年10月12日 0:52
  • 1 volatile 在目前的版本毫无意义  但是为了可能出现的将来的编译器优化  还是加上吧

    2  static 上下文  不存在this.

    恭喜自己5星用户达成
    • 已标记为答案 KeFang Chen 2009年10月12日 3:55
    2009年10月12日 2:05
    版主