是c#?

问题描述 投票:0回答:2

将使用C#ON .NET导致以下代码导致僵局?我担心

lock
声明不是伦特

class MyClass { private object lockObj = new object(); public void Foo() { lock(lockObj) { Bar(); } } public void Bar() { lock(lockObj) { // Do something } } }
    
c# .net multithreading locking deadlock
2个回答
171
投票
没有,只要您锁在同一对象上。 递归代码有效地有锁定,因此可以继续不受限制。

lock(object) {...}是使用

monitor

类的速记。 正如

marc指出的那样,
Monitor允许re-entrancy
,因此重复尝试锁定当前线程已经锁定的对象
对象,该对象已经锁定了。 如果您开始锁定不同的对象,那是您必须小心的时候。特别注意: 以同一顺序以给定数量的对象获取锁。 以您如何获取它们的方式,以

反向序列释放锁。

如果您违反了这两个规则中的任何一个,那么您几乎可以在某个点上遇到死锁问题。 the是一个很好的网页,描述了.net中的线程同步:Http://dotnetdebug.net/2005/07/07/20/monitor-class-class-avoiding-deadlocks/

  • 此外,一次锁定尽可能少的对象。考虑在可能的情况下考虑使用
  • 透明锁。这个想法是,如果您可以编写代码,以便有一个对象图,并且可以在该对象图的根上获取锁,那么请这样做。这意味着您在该根对象上有一个锁,因此不必担心您获得/发布锁的顺序。
  • (另一种说明,您的示例在技术上不是递归。为了使其递归,Bar()
  • 必须自称为迭代,通常是迭代的一部分。)

well,

Monitor允许重新进入,所以你不能自己死锁...所以不:不应该做

如果线程已经持有锁,那么它不会阻止自身。 .NET框架确保了这一点。您只需要确保两个线程不会尝试通过任何代码路径来序列相同的两个锁。 相同的线程可以多次使用相同的锁,但是您必须确保锁定锁定的锁定次数相同的次数。当然,只要您使用“锁定”关键字来完成此操作,它就会自动发生。

没有,此代码不会有死锁。 如果您真的想创建最简单的僵局,则需要至少2个资源。 考虑狗和骨骼场景。

狗对1个骨有完全控制,因此任何其他狗都必须等待。
狗分别锁定骨头并寻求其他骨头时,带有2个骨头的狗是最低的。


22
投票

© www.soinside.com 2019 - 2025. All rights reserved.