尽管我在我的应用程序中使用锁定,但我不明白锁定特定引用类型的确切原因.我认为它只是停止线程,直到{}的内容完成.但我已经读过锁定(这个)很糟糕,如果是公开的 – 为什么?文章解释了它,但我不明白我不知道对象本身被锁定的情况.
例如,如果我使用lock(this)并从另一个线程调用其方法怎么办?我以为只有锁下的代码受到保护,否则我将无法访问被锁定的对象?
谢谢
例如,如果我使用lock(this)并从另一个线程调用其方法怎么办?我以为只有锁下的代码受到保护,否则我将无法访问被锁定的对象?
谢谢
解决方法
托管堆上的每个对象都可以用作锁对象,这是一种在线程之间同步访问的方法.
I thought it just stops the thread until the content of {} is finished.
好吧,一个锁定它会阻止其他线程获取锁定,直到锁定被释放,这通常是在锁定语句结束时(但它也可能是一个Monitor.Wait).
锁(this)的使用是危险的,因为锁定是复杂的,并且准确理解哪些线程锁定哪个对象在哪个时间对于避免死锁是非常重要的;但是,如果你锁定(这个)你不能控制其他线程 – 这也可能(意外地)锁定同一个对象.使用私有字段进行锁定会更安全.
例如,如果你有(在同步列表中):
private IList<T> innerList = ... public int Count { get { lock(this) { return innerList.Count; } } }
然后不难想象另外一些代码也会引用这个同步列表并锁定它,例如:
SyncList<T> list = ... lock(list) { // lock for atomicity if(!list.Contains(value)) list.Add(value); }
这是一个潜在的僵局;如果Count没有锁定(这个),但锁定一个私人对象,即
private readonly object syncLock = new object(); public int Count { get { lock(syncLock) { return innerList.Count; } } }
现在没有这个问题的风险.这里的另一个问题是类似字段的事件和[MethodImpl]都会导致锁定(this).出于完全相同的原因,锁定类型(对于静态方法)同样是危险的.