繁体   English   中英

如何使调用内部集合线程安全?

[英]How to make a call internal collections thread-safe?

我有这样的班级组成。 类声明一个对象字典,这些对象本身具有一个内部字典对象。

    public class ValueObject
    {
        public float value = 0;
    }

    public class ValueDictionaryObject
    {
        private Dictionary<int, ValueObject> innerDict;

        public float GetTotalValue()
        {
            lock (((ICollection)this.innerDict).SyncRoot)
            {
                float total = 0f;
                foreach (var p in innerDict)
                    total += p.Value.value;
                return total;
            }
        }
    }

    public class OuterDictionaryObject
    {
        private Dictionary<int, ValueDictionaryObject> outerDict;

        public float GetTotalValueForSomeKey(int key )
        {
            lock (((ICollection)this.outerDict).SyncRoot)
            {
                return outerDict[key].GetTotalValue();
            }
        }
    }


    var outer = new OuterDictionaryObject();

从多个线程进行调用时出现问题,似乎发生了死锁

float result = outer.GetTotalValueForSomeKey(key);

如何使此调用线程安全?

从发布的代码中尚不清楚为什么会陷入僵局。 是的,您具有嵌套锁获取功能,这是死锁的先决条件。 但是,这里没有任何东西可以向我们展示您如何在某些情况下相对于此处看到的情况反转了锁获取顺序。

仍然...

您应该尽量避免在按住锁的同时调用任何东西。 有时这是不可避免的(例如,访问要同步访问的集合的成员,这意味着您必须调用该集合的成员)。 但是,只有在对您要解决的问题至关重要时,才应拨打电话。

在这里,似乎您可以像这样轻松地编写代码:

public class OuterDictionaryObject
{
    private Dictionary<int, ValueDictionaryObject> outerDict;

    public float GetTotalValueForSomeKey(int key )
    {
        ValueDictionaryObject vdo;

        lock (((ICollection)this.outerDict).SyncRoot)
        {
            vdo = outerDict[key];
        }

        return vdo.GetTotalValue();
    }
}

使用ConcurrentDictionary会产生类似的效果,因为直到对字典对象的同步访问完成之前,您不会调用GetTotalValue()方法。 因此恕我直言,这也是一个不错的选择。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM