静态变量的线程安全初始化我一直在使用这种模式来初始化我的类中的静态数据。它对我来说看起来很安全,但我知道线程问题有多么微妙。这是代码:publicclassMyClass//糟糕的代码,不要使用{staticstring_myResource="";静态挥发性布尔_init=false;publicMyClass(){如果(_init==true)返回;锁定(_myResource){如果(_init==true)返回;线程.睡眠(3000);//一些耗时较长的操作_myResource="HelloWorld";_init=真;}}publicstringMyResource{get{return_myResource;}}}这里有洞吗?也许有更简单的方法来做到这一点。更新:共识似乎是静态构造函数是可行的方法。我使用静态构造函数提出了以下版本。publicclassMyClass{staticMyClass()//静态构造函数{Thread.睡眠(3000);//一些耗时较长的操作_myResource="HelloWorld";}静态字符串_myResource=null;publicMyClass(){LocalString="本地操作";}//实例构造函数//使用但不修改publicboolMyResourceReady{get{return_myResource!=null;}}publicstringLocalString{get;放;我希望这更好。您可以使用静态构造函数初始化静态变量,C#保证每个AppDomain只调用一次。不确定您是否考虑过它们。所以你可以阅读这个:http://msdn.microsoft.com/en-us/library/aa645612(VS.71).aspx(静态构造函数)和这个:AreC#staticconstructorsthreadsafe?在_myResource上执行lock()并在lock()语句中更改它似乎是个坏主意。考虑以下工作流线程1调用MyClass()。执行在_init=true行停止;在_init=true之前;在分配_myResource。处理器切换到线程2。线程2调用MyClass()。由于_init还是false和_myResource,所以成功进入lock()语句块。_init仍然为false,因此线程2重新分配_myResource。解决方法:创建一个静态对象并锁定该对象而不是初始化资源:privatestaticreadonlyobject_resourceLock=newobject();/*...*/lock(_resourceLock){/*...*/}你的类不安全:一旦锁定,就可以更改锁定的对象。您有一个属性可以在不锁定资源的情况下获取资源。您正在锁定原始类型,这通常不是一个好习惯。这应该为你做:publicclassMyClass{staticreadonlyobject_sync=newobject();静态字符串_myResource="";静态挥发性布尔_init=false;publicMyClass(){如果(_init==true)返回;锁定(_sync){如果(_init==true)返回;线。睡眠(3000);//一些耗时较长的操作_myResource="HelloWorld";_init=真;}}publicstringMyResource{get{MyClassret;//正确的lock(_sync){ret=_myResource;返回ret;}}}更新:正确,不应直接返回静态资源...我已经相应地更正了我的示例。根据您的用例(即,如果线程不需要使用此变量相互传递信息),将成员变量标记为[ThreadStatic]可能是一种解决方案。看这里。静态字符串_myResource="";...publicMyClass(){...lock(_myResource){}}由于字符串驻留,您不应该锁定字符串文字。如果您锁定一个字符串文字并且多个类使用该字符串文字,那么您可能正在共享该锁。这可能会导致意外行为。以上就是《C#学习教程:静态变量的线程安全初始化》的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权请点击右侧联系管理员删除。如需转载请注明出处:
