首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >锁定对象到底是什么意思?

锁定对象到底是什么意思?
EN

Stack Overflow用户
提问于 2010-01-01 17:00:19
回答 5查看 1.9K关注 0票数 8

虽然我在我的应用程序中使用了锁,但我不明白在特定引用类型上锁到底是什么。我认为它只是停止线程,直到{}的内容完成。但是我读到过锁定(这)是不好的,如果它是公共的-为什么?这篇文章解释了它,但我不理解,因为我不知道对象本身被锁定发生了什么。例如,如果我使用lock(this)并从另一个线程调用它的方法怎么办?我以为只有锁下的代码是受保护的,否则我将根本无法访问锁定的对象?谢谢

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-01-01 17:06:45

托管堆上的每个对象都可以用作锁对象,这是一种在线程之间同步访问的方法。

我认为它只是停止线程,直到{}的内容结束。

lock会阻止其他线程获取锁,直到锁被释放,这通常发生在lock语句的末尾(但也可以是Monitor.Wait)。

lock(this)的使用是危险的,因为锁定很复杂,准确地了解哪些线程在此时锁定了哪些对象对于避免死锁非常重要;然而,如果您使用lock(this),您就无法控制其他线程--这些线程也可能(意外地)锁定同一对象。使用private字段进行锁定要安全得多。

举个例子,如果你有(在同步列表中):

代码语言:javascript
复制
private IList<T> innerList = ...
public int Count { get { lock(this) { return innerList.Count; } } }

然后不难想象,另一段代码也会引用这个同步列表,并锁定它,例如:

代码语言:javascript
复制
SyncList<T> list = ...
lock(list) { // lock for atomicity
    if(!list.Contains(value)) list.Add(value);
}

这是一个潜在的死锁;如果Count 没有 lock(this),而是锁定了一个私有对象,那会好得多。

代码语言:javascript
复制
private readonly object syncLock = new object();
public int Count { get { lock(syncLock) { return innerList.Count; } } }

现在不存在这个问题的风险。这里的另一个问题是,类字段事件和[MethodImpl]都会导致lock(this)。出于完全相同的原因,锁定Type (对于静态方法)也同样危险。

票数 8
EN

Stack Overflow用户

发布于 2010-01-01 17:07:15

对象本身并未锁定。可以将每个对象看作有一个关联的锁(或监视器)。当一个线程获得锁时,除非第一个线程释放锁,否则其他线程都无法获得锁,这可以通过调用Monitor.Exit (这是在lock语句结束时发生的事情)或通过调用Monitor.Wait来实现。调用Monitor.Enter获取锁的线程将会阻塞,直到它能够获取锁为止。

对象本身根本不是“受保护的”--锁基本上是建议的。

不锁定"this“的原因是您不知道哪些其他代码引用了"this”。要获得正确的锁定,您需要知道在哪些情况下线程会或不会拥有锁-而您无法知道控制之外的代码是否可以取出锁。例外情况是为了显式地共享锁而公开引用(如.NET 1.1集合上的SyncRoot属性)。

票数 8
EN

Stack Overflow用户

发布于 2010-01-01 17:08:04

锁定对象对对象本身没有任何影响-它只是意味着任何其他试图锁定同一对象的线程都将被停止,直到锁定线程释放它。锁(This)不受欢迎的原因是,对象外部的其他代码也可以锁定对象,从而干扰其正常操作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1988216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档