在我下面的不安全类中,如果没有先获得锁定,可以采取哪些措施来阻止某人执行不安全的方法?
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()
现在可以被不具备锁定的线程调用。
答案 0 :(得分:5)
您应该能够使用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之前,AFAIK处理此问题的唯一方法是在同步对象旁边使用线程静态布尔值,在退出之后输入true
之后设置为false
。同样的布尔值 - 调用它callerHasLock
,以符合上面的代码 - 然后可以在锁定上下文中进行测试,结果与Monitor.IsEntered
相同。