c# – 为什么这段代码不会以死锁结束
我有这个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模式更便宜,而且非常纤薄. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |