C# 中使用 lock 语句的递归/嵌套锁定
可能的重复:
C# 中的可重入锁
我在 StackOverflow 和 MSDN,不敢相信我找不到这个挥之不去的问题在互联网上。
假设我有一个带有私有成员的类,我想在多个公共方法中访问该成员。这些公共方法将被不同的线程调用,因此需要同步。
public class MyClass
{
private Object SomeSharedData = new Object();
public void MethodA()
{
lock( SomeSharedData) {
// do something
MethodB();
}
}
public void MethodB()
{
lock( SomeSharedData) {
// do something
}
}
}
请注意,MethodA 和 MethodB 可以由此类的用户调用,但 MethodA 也会调用 MethodB,这会导致嵌套锁定条件。
这样就保证安全了吗?换句话说,.NET 是否通过对锁进行引用计数来处理此问题,以便当我弹出这些方法时,锁会递减?或者.NET 在幕后施展了某种魔法,从而简单地忽略了源自同一线程的对象上的所有后续锁定?
Possible Duplicate:
Re-entrant locks in C#
I've looked here on StackOverflow and on MSDN, and can't believe that I couldn't find this question lingering out there on the internets.
Let's say I have a class with a private member that I want to access in several public methods. These public methods will be called by different threads, hence the need for synchronization.
public class MyClass
{
private Object SomeSharedData = new Object();
public void MethodA()
{
lock( SomeSharedData) {
// do something
MethodB();
}
}
public void MethodB()
{
lock( SomeSharedData) {
// do something
}
}
}
Note that MethodA and MethodB can be called by users of this class, but MethodA also calls MethodB, which results in a nested locking condition.
Is this guaranteed to be safe? In other words, does .NET handle this by reference counting the lock, so that as I pop out of these methods, the lock gets decremented? Or is .NET performing some magic behind the scenes, whereby it simply ignores all subsequent locks on the object originating from the same thread?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,.NET 中基于
Monitor
的锁是递归的,并且是计数的。从
Monitor.Enter
的文档中:这究竟是好事还是坏事还有待商榷……
Yes, locks based on
Monitor
in .NET are recursive, and counted.From the docs for
Monitor.Enter
:Whether this is a good thing or not is up for debate...
是的,Monitor 支持递归,但您应该之所以意识到,是因为这种行为因一种同步原语而异于另一种同步原语。
例如,默认情况下 ReaderWriterLockSlim 不支持递归并且此代码片段抛出异常:
Yes, Monitor support recursion, but you should be aware because this behavior differs from one synchronization primitive to another.
For example, ReaderWriterLockSlim by default doesn't support recursion and this code snippet throws exception: