锁在里面锁
我想知道如果这个build设会导致一个错误:
lock(sync) { // something lock(sync) { //something lock(sync) { //something } } }
我已经运行这个代码,这似乎很好,但也许在某些情况下可能会引发错误?
lock
是Monitor.Enter
和Monitor.Exit
的包装 :
lock
关键字在块的开始处调用Enter
,在块的结尾处调用Exit
。 从前者的文件:
从Monitor.Enter
的文档 :
同一个线程在不阻塞的情况下多次调用
Enter
是合法的; 但是,等待对象的其他线程将被解除阻塞之前,必须调用相同数量的Exit
调用。
由于“ Enter
和“ Exit
的调用是成对的,因此您的代码模式具有良好定义的行为。
但是,请注意, lock
不能保证是一个无例外的构造:
如果
Interrupt
中断正在等待inputlock
语句的线程,则会抛出ThreadInterruptedException
。
解释为什么它是明确的行为,永远不会失败:
除此之外: 这个答案有关锁实际工作的更好的细节
该锁发生在Thread
级别,因此在同一线程上再次调用它将是多余的。 我认为它不会有任何的性能损失(虽然这将取决于.Net的内部是如何写的,所以我不能保证)
很多时候,你会有一个公共函数调用你的class级中的另一个公共职能,他们在分开使用时都需要锁。 如果这不被允许,以下将失败:
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); } }
根据MSDN(见这里和这里 )这是明确的行为,并没有问题。