其他分享
首页 > 其他分享> > 标签:ReaderWriterLockSlim vs Double Lock Check pattern

标签:ReaderWriterLockSlim vs Double Lock Check pattern

作者:互联网

编辑:从我已经得到的答案中,我了解到我提出的第一个解决方案,并不是真正的“不阻止读取”,因为只有一个线程可以输入可升级的锁,而在读取被释放之前不能采用写入锁…

所以我的问题是,如果不存在,如何以正确的方式使第一个解决方案成为“非阻塞读取”?

我试图了解两种非阻塞多线程读取的解决方案.以下两个解决方案之间有什么区别(也许我仍然不了解某些事情,但是我正在尝试):

/// <summary>
/// ReaderWriterLockSlim pattern
/// </summary>
public class ReadWriteLockCheck
{
    Dictionary<string, object> _dict = new Dictionary<string, object>();

    private ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);

    public void CreateByKey(string key)
    {
        _rwLock.EnterReadLock();
        try
        {
            if (!_dict.ContainsKey(key)) //Non blocking read - Check if exists
            {
                _rwLock.EnterWriteLock(); //Lock
                try
                {
                    _dict.Add(key, new object());
                }
                finally
                {
                    _rwLock.ExitWriteLock();
                }
            }
        }
        finally
        {
            _rwLock.ExitReadLock();
        }
    }

    public bool GetByKey(string key)
    {
        _rwLock.EnterWriteLock();
        try
        {
            if (_dict.ContainsKey(key)) //Non blocking read
            {
                return true;
            }

            return false;
        }
        finally
        {
            _rwLock.ExitReadLock();
        }
    }
}

/// <summary>
/// Double check lock pattern
/// </summary>
public class MonitorLock
{
    Dictionary<string, object> _dict = new Dictionary<string, object>();

    private object _syncObj = new Object();

    public void CreateByKey(string key)
    {
        if (!_dict.ContainsKey(key)) //Non blocking read - Check if exists
        {
            Monitor.Enter(_syncObj); //Lock
            try
            {
                if (!_dict.ContainsKey(key)) //Check if between first check and lock someone already added
                {
                    _dict.Add(key, new object());
                }
            }
            finally
            {
                Monitor.Exit(_syncObj);
            }
        }
    }

    public bool GetByKey(string key)
    {
        if (_dict.ContainsKey(key)) //Non blocking read
        {
            return true;
        }

        return false;
    }
}

在我看来,这两种解决方案都可以进行非阻塞读取,并且只能在写入时进行阻塞…如果是这样,ReaderWriterLockSlim有什么好处?正如我在google中发现的那样,Monitor比ReaderWriterLockSlim快得多.
当然,我知道阅读时可能会得到不正确的字典状态,但是对我来说还可以.
谢谢

解决方法:

From MSDN

Only one thread can enter upgradeable mode at any given time

基本上,您没有比使用完全锁定做得更好-锁定实际上会更快.

奇怪的是,哈希表是一种很好的方法.尤其是因为值是object,并且键是引用类型(不需要额外的装箱).哈希表是不寻常的,因为读取是完全线程安全的.您只需要警惕多个作者.

例如:

readonly Hashtable lookup = new Hashtable();

...

object val = lookup[key]; // no need to synchronize when reading

...

lock(lookup)
{
    lookup[key] = newVal; // synchronize when writing
}

标签:multithreading,locking,readerwriterlockslim,c,net
来源: https://codeday.me/bug/20191031/1975618.html