在下面的不安全类中,可以采取什么措施来防止某人在没有先获取锁的情况下执行不安全方法?
class Unsafe
{
private static readonly object lockObj;
void MethodA()
{
lock (lockObj)
{
// do some things
DoUnsafeThing();
}
}
void MethodB()
{
lock (lockObj)
{
// do some things
DoUnsafeThing();
}
}
void DoUnsafeThing()
{
if (callerHasLock)
// Do the unsafe thing
else
return; // or throw some exception
}
}
可以选择在 DoUnsafeThing()
内再次获取锁:
void DoUnsafeThing()
{
lock (lockObj)
{
// Do the unsafe thing
}
}
但是 DoUnsafeThing()
现在可以由尚未拥有锁的线程调用。
最佳答案
您应该能够使用Monitor.IsEntered()验证线程本身是否已经获得锁:
void DoUnsafeThing()
{
if (Monitor.IsEntered(lockObj))
// Do the unsafe thing
else
return; // or throw some exception
}
您可以使用Monitor
使用锁的类。在 C# 中,lock(...)
语句只是 Monitor.Enter(o); try {...} finally {Monitor.Exit(o);}
的语法糖。 。其中还有其他选项可用于微调。请记住,多线程很困难。了解您的工具集。
编辑:(响应框架版本问题更新)
在 .NET 4.5 之前,据我所知,处理此问题的唯一方法是在同步对象旁边使用线程静态 bool 值,设置为 true
进入后不久 false
就在退出之前。同样的 bool 值——称之为 callerHasLock
,以符合上面的代码 - 然后可以在锁定上下文中进行测试,结果与 Monitor.IsEntered
相同.
关于c# - 如何创建一个仅在调用线程持有锁时才运行的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23548619/