是否可以使用以下'线程安全双重检查懒惰初始化'模式?

Dre*_*mer 5 .net c# multithreading

框架:.net 4.5

我使用下面的示例代码模式以线程安全的方式初始化变量.最近我一直在阅读一些文章,这些文章解释了"在某些平台上已经破坏了双重检查锁定http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html "但看起来对我来说没问题.我正在使用.net 4.5.

根据评论提出建议

建议使用lazy并让.net框架在处理基于平台的线程安全和内存模型上做大量工作:):http://msdn.microsoft.com/en-us/library/dd642331.aspx

更新

似乎Eric Lippert一直建议不要使用这种模式(现在很困惑:() 这种模式的名称?(答案:使用双重检查锁定进行延迟初始化) C#手动锁定/解锁

更新2

下面的摘录是"像所有删除读锁的技术一样,图7中的代码(类似于我的代码)依赖于强写入顺序.例如,这个代码在ECMA内存模型中是不正确的,除非myValue变得易失,因为初始化LazyInitClass实例的写入可能会延迟到写入myValue之后,允许GetValue的客户端读取未初始化的状态.在.NET Framework 2.0模型中,代码在没有volatile声明的情况下工作.来自http://msdn.microsoft.com/en-us/magazine/cc163715.aspx

而且我也没有使用'volatile',因为许多示例都显示在不同的代码片段中.我也假设它也可以(参考:.NET中双重检查锁定需要volatile修饰符)

****psudeo代码 - 它解释了我正在使用的版本 - 构建于.net 4.5****之上

static private object s_syncObject = new object();
private static string s_lazyInitializedVariable = null;
//is it necessar to make the backing varible volatie?
//private static volatile string s_lazyInitializedVariable = null;
private static string LazyInitializedVariable
{
    get
    {
        if(string.IsNullOrWhiteSpace(s_lazyInitializedVariable))
        {
            lock(s_syncObject)
            {
                if (string.IsNullOrWhiteSpace(s_lazyInitializedVariable))
                {
                    /*
                        * my lazy initialization code
                        */
                    s_lazyInitializedVariable = "Initialized";
                }
            }
        }
        return s_lazyInitializedVariable;
    }
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以确认一下吗?基本上下面是我的假设,因为我正在使用.net 4.5

  1. 我假设可以使用下面的代码并忽略volatile语句?如果我的假设是好的,请批准.

注意:我也注意到我可以使用.net 4.0中引入的'lazy'.但是现在我会按照我的方式生活,我猜,正如我已经看到使用ILSpy实现懒惰,并且看起来它为我这样的简单任务做了相对更多的事情......

最好的祝福.

vto*_*ola 0

看看这篇关于 C# 中单例的文章:http://www.yoda.arachsys.com/csharp/singleton.html

它探讨了不同的技术(包括双重检查锁)及其含义,并推荐以下一种技术:

public sealed class Singleton
{
    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            return Nested.instance;
        }
    }

    class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly Singleton instance = new Singleton();
    }
}
Run Code Online (Sandbox Code Playgroud)