1

我对静态类的静态成员的初始化有问题。据我所知,它只会被初始化一次,所以我在并发执行 fooList.Add(...) 时锁定了这个变量,以确保这个操作是线程安全的:

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

    public void functionA()
    {
       lock (_lockAdd)
       {...

我遇到了一些奇怪的情况,所以我决定用log4net编写_lockAdd的hashcode,令我惊讶的是我观察到的是:

【INFO】【2012-04-20 15:26:44,080】【thread12】_lockAdd的hashcode(51755728)...

【INFO】【2012-04-20 15:26:58,624】【thread16】_lockAdd的hashcode(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(...)
                }
            }
        }
    }
}
4

2 回答 2

1

对于仅用于locking 的对象,请使用readonly

private static readonly object _lockAdd = new object();

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

于 2012-04-21T17:38:10.687 回答
0

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

于 2012-04-23T01:21:28.437 回答