C# 初始化静态类的静态成员时的奇怪行为

C# 初始化静态类的静态成员时的奇怪行为,c#,concurrency,static,locking,initialization,C#,Concurrency,Static,Locking,Initialization,我在初始化静态类的静态成员时遇到问题。据我所知,它将只初始化一次,因此我在并发执行愚弄者添加(…)时锁定此变量,以确保此操作是线程安全的: internal static class ObjectA { private static object _lockAdd = new object(); public void functionA() { lock (_lockAdd) {... 我遇到了一些奇怪的情况,所以我决定用log4net编

我在初始化静态类的静态成员时遇到问题。据我所知,它将只初始化一次,因此我在并发执行愚弄者添加(…)时锁定此变量,以确保此操作是线程安全的:

internal static class ObjectA
{
    private static object _lockAdd = new object();

    public void functionA()
    {
       lock (_lockAdd)
       {...
我遇到了一些奇怪的情况,所以我决定用log4net编写_lockAdd的hashcode,让我惊讶的是,我观察到:

【信息】【2012-04-20 15:26:44080】【线程12】 _lockAdd的哈希代码(51755728)

【信息】【2012-04-20 15:26:58624】【线程16】 _lockAdd的哈希代码(31071611)

正如您所看到的,这两个“_lockAdd”地址是不同的,为什么会这样,或者我对静态成员的理解是错误的?当操作在静态类中时,如何确保线程安全

对不起,伪代码错误,这是我的实际代码:

internal static class UtilExtension
{               
    private static object _lockAdd = new object(); //initial twice ? why?

    public static void DoAdd(this Type entityType)
    {            
        if (!Pools.Has(entityType))
        {
            lock (_lockAdd) 
            {
                if (!Pools.Has(entityType)) //insure operation below is thread safe
                {
                    // i find something wrong in concurrency,so i log the _lockAdd's hashcode,
                    // and then i found it's hashcode is different( in my opinion, it means not the same variables )
                    LogUtil.Info(_lockAdd.GetHashCode().ToString());

                    //... do fooList.Add(...)
                }
            }
        }
    }
}

对于仅用于锁定的对象,请使用只读:

private static readonly object _lockAdd = new object();

如果对象以某种方式被覆盖,下次启动应用程序时,您很可能从编译器或运行时获得不同的结果。

对于仅用于
锁定的对象,请使用
只读

private static readonly object _lockAdd = new object();

如果对象以某种方式被覆盖,下次启动应用程序时,您很可能会从编译器或运行时获得不同的结果。

也许我让它变得复杂了,事实是,静态成员总是线程不安全的。因此,当我们使用静态成员(\u lockAdd)作为锁定目标时,我们应该添加readonly以确保_lockAdd只初始化一次。

也许我把它弄复杂了,事实是,静态成员总是线程不安全的。因此,当我们使用静态成员(_lockAdd)作为锁定目标时,我们应该添加readonly以确保_lockAdd只初始化一次。

你为什么要这样做?!请张贴您的实际代码。您提供的不会编译(您有一个带有非静态成员函数的静态类)。您看到的行为似乎已将ThreadStatic属性应用于静态锁对象。是否涉及多个AppDomains?该成员的hashcode是什么意思?你到底是怎么得到它的?@Jon Skeet,不,只有一个域,我启动N个线程来测试锁的问题。你为什么要这样做?!请张贴您的实际代码。您提供的不会编译(您有一个带有非静态成员函数的静态类)。您看到的行为似乎已将ThreadStatic属性应用于静态锁对象。是否涉及多个AppDomains?该成员的hashcode是什么意思?你到底是怎么得到它的?@Jon Skeet,不,只有一个域,我启动了N个线程来测试锁的问题,我仍然对静态成员感到困惑,它怎么能初始化两次,即使没有添加readonly,我仍然对静态成员感到困惑,它怎么能初始化两次,即使没有添加readonly