在我下面的不安全类中,可以做些什么来防止有人在没有先获得锁的情况下执行不安全的方法?
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 相同.
