侧边栏壁纸
博主头像
张种恩的技术小栈博主等级

行动起来,活在当下

  • 累计撰写 748 篇文章
  • 累计创建 65 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

多线程下的单例-Double check

zze
zze
2017-05-13 / 0 评论 / 0 点赞 / 372 阅读 / 2100 字

不定期更新相关视频,抖音点击左上角加号后扫一扫右方侧边栏二维码关注我~正在更新《Shell其实很简单》系列

话不多说直接上代码:

public sealed class Singleton
{
    private static Singleton _instance = null;
    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;
        }
    }
}

很久之前就看到这段代码,一直理解不了为啥要判断两次是否为空。刚刚画着图的时候突然就明白了,见下图:
image.png
假如上图还是没看明白的话,可以看下面一段没有两次判空的情况与上面作对比,如下:

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

    Singleton(){}

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

分析见下图:
image.png
看完上面先不要着急,再下面这段代码:

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

    Singleton(){}

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

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

这里我是这样理解的:线程安全的实现其实就是要进行同步操作,而我们只需在同步操作之前,判断该实例是否为 null 就可以降低通过被 lock 的次数了,这样就是经典的 Double-Checked Locking 了。

0

评论区