我想知道这种构造是否会导致错误:
lock(sync)
{
// something
lock(sync)
{
//something
lock(sync)
{
//something
}
}
}
我已经运行了这段代码,看起来还不错,但是在某些情况下可能会引发错误?
我想知道这种构造是否会导致错误:
lock(sync)
{
// something
lock(sync)
{
//something
lock(sync)
{
//something
}
}
}
我已经运行了这段代码,看起来还不错,但是在某些情况下可能会引发错误?
Answers:
lock
是的包装Monitor.Enter
和Monitor.Exit
:
该
lock
关键字要求Enter
在该块的开始和Exit
在块的结尾。从前者的文档中:
同一线程在
Enter
不阻塞的情况下多次调用是合法的。但是,Exit
必须等待相等数量的调用,然后等待该对象的其他线程才能解除阻塞。
因为,在两个电话Enter
和Exit
配对,你的代码模式有明确定义的行为。
但是请注意,这lock
不能保证是无异常的构造:
ThreadInterruptedException
如果Interrupt
中断正在等待输入lock
语句的线程,则抛出A。
lock
s本质上是多余的:您已经拥有锁;再次要求它永远不会失败。
要解释为什么它是定义良好的行为并且永远不会失败:
锁定发生在该Thread
级别,因此在同一线程上第二次调用将是多余的。我认为它不会有任何性能上的损失(尽管这将取决于.Net内部的精确编写方式,因此我不能保证)
很多时候,您会有一个公共函数来调用您的类中的另一个公共函数,这两个公共函数在单独使用时都需要锁。如果不允许这样做,则以下操作将失败:
private Dictionary<string, int> database = new Dictionary<string, int>();
private object databaseLock = new object();
public void AddOrUpdate(string item)
{
lock (databaseLock)
{
if (Exists(item))
database.Add(item, 1);
else
++database[item];
}
}
public bool Exists(string item)
{
lock (databaseLock)
{
//... Maybe some pre-processing of the key or item...
return database.ContainsKey(item);
}
}