Tho*_*mas 6 c# multithreading locking
尽管我在我的应用程序中使用锁定,但我不明白锁定特定引用类型的确切原因.我认为它只是停止线程,直到{}的内容完成.但我已经读过锁定(这个)很糟糕,如果是公开的 - 为什么?文章解释了它,但我不明白我不知道对象本身被锁定的情况.例如,如果我使用lock(this)并从另一个线程调用其方法怎么办?我以为只有锁下的代码受到保护,否则我将无法访问被锁定的对象?谢谢
托管堆上的每个对象都可以用作锁对象,这是一种在线程之间同步访问的方法.
我认为它只是停止线程,直到{}的内容完成.
好吧,lock
它会阻止其他线程获取锁,直到锁被释放,这通常是在lock
语句结束时(但它也可能是a Monitor.Wait
).
的lock(this)
使用是危险的,因为锁是复杂的,了解究竟哪些线程锁定哪个对象(S),此时是为了避免死锁非常重要; 但是,如果你lock(this)
不能控制其他线程 - 这也可能(意外地)锁定同一个对象.使用private
字段进行锁定要安全得多.
例如,如果你有(在同步列表中):
private IList<T> innerList = ...
public int Count { get { lock(this) { return innerList.Count; } } }
Run Code Online (Sandbox Code Playgroud)
然后不难想象另外一些代码也会引用这个同步列表并锁定它,例如:
SyncList<T> list = ...
lock(list) { // lock for atomicity
if(!list.Contains(value)) list.Add(value);
}
Run Code Online (Sandbox Code Playgroud)
这是一个潜在的僵局; 如果Count
不 这样做会好得多lock(this)
,但锁定一个私人对象,即
private readonly object syncLock = new object();
public int Count { get { lock(syncLock) { return innerList.Count; } } }
Run Code Online (Sandbox Code Playgroud)
现在没有这个问题的风险.这里的另一个问题是类似字段的事件和[MethodImpl]
原因lock(this)
.Type
出于完全相同的原因,锁定(对于静态方法)同样是危险的.
对象本身未锁定.将每个对象视为具有关联的锁(或监视器).当一个线程获得锁定时,没有其他线程可以在没有第一个线程释放它的情况下通过调用Monitor.Exit
(这是在lock
语句结束时发生的事情)或通过调用来获取它Monitor.Wait
.调用Monitor.Enter
获取锁的线程将阻塞,直到它可以获取锁.
对象本身根本不受"保护" - 锁定基本上是建议性的.
不锁定"this"的原因是你不知道其他代码对"this"的引用.获得正确的锁定需要您知道线程将在哪些情况下拥有锁定 - 并且您无法知道控制之外的代码是否可以取消锁定.例外情况是,如果您为了共享锁的明确目的而公开引用(如SyncRoot
.NET 1.1集合上的属性).
归档时间: |
|
查看次数: |
1539 次 |
最近记录: |