首页 > 代码库 > 多线程下的单例-double check

多线程下的单例-double check

  话不多说直接上代码:

  

public sealed class Singleton
{
    private static Singleton _instance = null;
    // Creates an syn object.
    private static readonly object SynObject = new object();

    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            // Double-Checked Locking
            if (null == _instance)
            {
                lock (SynObject)
                {
                    if (null == _instance)
                    {
                        _instance = new Singleton();
                    }
                }
            }
            return _instance;
        }
    }
}

  很久之前就看到这段代码,一直理解不了为啥要判断两次是否为空.刚刚画着图的时候突然就明白了,见下图:

  技术分享

  假如上图还是没看明白的话,可以看下面一段没有两次判空的情况,首先代码如下:

  

public sealed class Singleton
{
    private static Singleton _instance = null;
    // Creates an syn object.
    private static readonly object SynObject = new object();

    Singleton()
    {
    }

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

  分析见下图:

  技术分享

 看完上面先不要着急,先看下面这段代码:

  

public sealed class Singleton
{
    private static Singleton _instance = null;
    private static readonly object SynObject = new object();

    Singleton()
    {
    }

    /// <summary>
    /// Gets the instance.
    /// </summary>
    public static Singleton Instance
    {
        get
        {
            lock (SynObject)
            {
                return _instance ?? (_instance = new Singleton());
            }
        }
    }
}
 

  看到这里有些同学可能会产生疑问,以上方式的实现方式是线程安全的,如果像上面代码段进行一次判断也是可以实现多线程下单例的,为什么要判断两次呢?

  这里我是这样理解的:线程安全的实现方式的问题是要进行同步操作,那么我们可以降低通过操作的次数,所以我们只需在同步操作之前,添加判断该实例是否为null就可以降低通过操作的次数了,这样就是经典的Double-Checked Locking方法了。

 

 

多线程下的单例-double check