同一功能中的多重锁定

时间:2009-06-19 21:43:48

标签: c# multithreading

我有一个函数是我的应用程序的主要瓶颈,因为它对线程之间共享的全局列表进行了大量的字符串比较。我的问题基本上是这样的:

在1个函数中多次锁定列表(称为List gList)是不好的。然后再次将其锁定(在执行查找时基本锁定,解锁以准备插入新项目,然后再次锁定并添加新项目)。

当我你是一个探查者时,我没有看到任何迹象表明我为此付出了沉重的代价,但是我可能会在以后的某个时间点,或者当它在野外编码时?在这方面,任何人都有最好的实践或个人经历吗?

4 个答案:

答案 0 :(得分:5)

你如何进行锁定?如果情况不是这样,您可能希望使用ReaderWriterLockSlim

这是一个简单的用法示例:

class SomeData
{
    private IList<string> _someStrings = new List<string>();
    private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();

    public void Add(string text)
    {
        _lock.EnterWriteLock();            
        try
        {
            _someStrings.Add(text);
        }
        finally
        {
            _lock.ExitWriteLock();
        }

    }

    public bool Contains(string text)
    {
        _lock.EnterReadLock();
        try
        {
            return _someStrings.Contains(text);
        }
        finally
        {
            _lock.ExitReadLock();
        }
    }
}

答案 1 :(得分:1)

通常,您希望锁定尽可能短的时间。争用的成本远远高于无争用锁定获取的成本(可以在用户空间中完成),因此即使意味着获取锁定次数。

尽管如此,请确保在适当的情况下对此进行分析:同时负载量很大。否则你的结果与现实没什么关系。

答案 2 :(得分:1)

在我看来,很少有数据可以给出具体答案。通常,锁的数量不会产生性能问题,而是等待该锁的线程数。

答案 3 :(得分:1)

听起来你不想释放查找和插入之间的锁定。要么就是这样,要么在查找​​期间根本不需要锁定。

您是否仅在元素尚未存在时才尝试添加到列表中?如果是这样,那么在准备元素时,释放两个步骤之间的锁定允许另一个线程添加到列表中。当您准备添加时,您的查找已过期。

如果查找可能已过期不是问题,那么您可能根本不需要在查找期间锁定。