单例模式——双检锁

作者:追风剑情 发布于:2017-8-12 16:07 分类:C#

using System;
using System.Threading;

namespace Test1
{
    class Program
    {
        static void Main(string[] args)
        {
        }
    }

    public sealed class Singleton
    {
        private static Object s_lock = new Object();

        // 这个字段引用一个单例实例对象
        private static Singleton s_value = null;

        // 私有构造器阻止这个类外部的任何代码创建实例
        private Singleton()
        {
            //把初始化单实例对象的代码放在这里...
        }

        // 以下公共静态方法返回单实例对象(采用双检锁技术,Double-Check Locking)
        public static Singleton GetSingleton()
        {
            if (s_value != null) return s_value;

            Monitor.Enter(s_lock);
            if (s_value == null)
            {
                //编译器可能会这样做:
                //1.为Singleton分配内存并把引用发布给temp
                //2.最后执行Singleton的构造器

                //所以如果这样写s_value=new Singleton();那么
                //其他线程可能拿到一个尚未执行构造器的s_value对象。
                Singleton temp = new Singleton();

                //Volatile保证了Singleton构造器执行结束后,才把引用发布到s_value
                Volatile.Write(ref s_value, temp);
            }
            Monitor.Exit(s_lock);

            return s_value;
        }
    }
}


lock(obj){ }Monitor 的语法糖。类似如下代码:

try
{
	Monitor.Enter(obj);
	dosomething();
}
catch(Exception ex)
{
	
}
finally
{
	Monitor.Exit(obj);
}


官方文档:Volatile类

标签: C#

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号