加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 为什么这段代码不会以死锁结束

发布时间:2020-12-15 20:03:46 所属栏目:百科 来源:网络整理
导读:我有这个C#代码: public class Locking{ private int Value1; private int Value2; private object lockValue = new Object(); public int GetInt1(int value1,int value2) { lock (lockValue) { Value1 = value1; Value2 = value2; return GetResult(); }
我有这个C#代码:

public class Locking
{

    private int Value1; private int Value2;

    private object lockValue = new Object();
    public int GetInt1(int value1,int value2)
    {
        lock (lockValue)
        {
            Value1 = value1;
            Value2 = value2;
            return GetResult();
        }

    }

    public int GetInt2(int value1,int value2)
    {
        lock (lockValue)
        {
            return GetInt1(value1,value2);
        }
    }

    private int GetResult()
    {
        return Value1 + Value2;
    }


}

所以基本上我期望一个死锁,如果我执行GetInt2但代码只是执行.任何好的解释.

解决方法

这里的一般情况是同步对象是否可重入.换句话说,如果已经拥有锁,则可以通过相同的线程再次获取.另一种说法是对象是否具有“线程亲和力”.

在.NET中,Monitor类(实现lock语句),Mutex和ReaderWriterLock是可重入的. Semaphore和SemaphoreSlim类不是,您可以使用二进制信号量使代码死锁.实现锁定的最便宜的方法是使用Interlocked.CompareExchange(),它也不会重入.

使同步对象可重入需要额外的成本,它需要跟踪哪个线程拥有它以及在拥有线程上获取锁的频率.这需要存储Thread.ManagedId和一个计数器,两个整数.这影响了C中的选择,例如,C 11语言规范最终将线程添加到标准库. std :: mutex类在该语言中不可重入,并且拒绝添加递归版本的提议.他们考虑了使其重入过高的开销.也许有点笨手笨脚,花费在调试意外死锁上花费的时间相当微不足道的成本:)但它是一种语言,它不是灌篮,获得线程ID可以保证像它一样便宜.净.

这在ReaderWriterLockSlim类中公开,您可以选择.请注意RecursionPolicy属性,允许您在NoRecursion和SupportsRecursion之间进行选择. NoRecursion模式更便宜,而且非常纤薄.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读