重入在C#中的锁 [英] Re-entrant locks in C#

查看:647
本文介绍了重入在C#中的锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请问以下code结果使用C#.NET的一个僵局?

  MyClass类
 {
    私有对象lockObj =新的对象();

    公共无效美孚()
    {
        锁定(lockObj){
             酒吧();
        }
    }

    公共无效酒吧()
    {
        锁定(lockObj){
          // 做一点事
        }
    }
 }
 

解决方案

没有,不是只要你锁定了同一个对象。递归code有效的已经具备了锁定等可以继续畅通无阻。

锁(对象){...} 是缩写使用的Monitor 类。由于马克指出显示器允许的 重入 的,如此反复尝试锁定一个对象的在当前线程已经拥有锁将工作得很好。

如果你开始就锁定的不同的的对象,当你必须要小心的。特别注意:

  • 始终获得在同一序列的对象的给定数量的锁。
  • 始终释放锁在逆转顺序如何获得它们。

如果你违反任何这些规则,你是pretty的多少保证得到僵局问题的在某些时候的。

下面是.NET一个很好的网页描述线程同步:<一href="http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/">http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/

此外,锁定的同时尽可能少的对象。还考虑领域驱动设计中的概念=htt​​p://thinkddd.com/glossary/aggregate -root />总根,并申请粗粒度的锁在可能的情况。我们的想法是,如果你可以写你的code等,有一个对象图,你可以获取锁在该对象图的根,那么这样做。这意味着你有一个根对象上一把锁,因此不必太在乎在你获得序列/释放锁。

(一进一步指出,你的榜样是不是技术上递归的。因为这是递归的,酒吧()将不得不自称,一般的一部分的一次迭代。)

Will the following code result in a deadlock using C# on .NET?

 class MyClass
 {
    private object lockObj = new object();

    public void Foo()
    {
        lock(lockObj){ 
             Bar();
        }
    }

    public void Bar()
    {
        lock(lockObj){ 
          // Do something 
        }
    }       
 }

解决方案

No, not as long as you are locking on the same object. The recursive code effectively already has the lock and so can continue unhindered.

lock(object) {...} is shorthand for using the Monitor class. As Marc points out, Monitor allows re-entrancy, so repeated attempts to lock on an object on which the current thread already has a lock will work just fine.

If you start locking on different objects, that's when you have to be careful. Pay particular attention to:

  • Always acquire locks on a given number of objects in the same sequence.
  • Always release locks in the reverse sequence to how you acquire them.

If you break either of these rules you're pretty much guaranteed to get deadlock issues at some point.

Here is one good webpage describing thread synchronisation in .NET: http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/

Also, lock on as few objects at a time as possible. Consider also the Domain Driven Design concept of aggregate roots, and apply coarse-grained locks where possible. The idea being that if you can write your code such that there is an object graph and you can acquire locks on the root of that object graph, then do so. This means you have one lock on that root object and therefore don't have to worry so much about the sequence in which you acquire/release locks.

(One further note, your example isn't technically recursive. For it to be recursive, Bar() would have to call itself, typically as part of an iteration.)

这篇关于重入在C#中的锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆