为什么C#需要锁对象?

为什么C#需要锁对象?,c#,thread-safety,locking,C#,Thread Safety,Locking,您有时可以将对象本身重新用于锁,但通常还是建议使用不同的对象 如果仅仅有一个锁的关键字,我们不是有更多的类型安全性和更好的意图吗 private object _MyLock = new object(); // someone would now be able to reassign breaking everything _MyLock = new object(); lock ( _MyLock ) ... VS 在我获得否决票之前,你无法猜到有人的意图:我很确定语言设计师

您有时可以将对象本身重新用于锁,但通常还是建议使用不同的对象

如果仅仅有一个锁的关键字,我们不是有更多的类型安全性和更好的意图吗

private object _MyLock = new object();

// someone would now be able to reassign breaking everything
_MyLock = new object();

lock ( _MyLock )
    ...
VS


在我获得否决票之前,你无法猜到有人的意图:我很确定语言设计师有一个很好的理由,这里有更多的知识渊博的程序员,这就是为什么。我这样做是为了更好地理解编程原理。

一种解决方案可能是将锁对象定义为
只读

static readonly object lockObject = new object();

在这种情况下,编译器会阻止更新新对象并将其分配给
lockobject

注意,通过将对象用作监视器,您已经可以对任何其他对象执行所有可以执行的操作:传递引用以便多个类可以共享同一监视器,将它们保留在数组中,将它们保留在其他数据结构中

如果您有一种特殊类型的可锁定声明,则需要使用特殊语法将其传递给函数、在另一个实例中存储对它的引用、将其与类型而不是实例关联、创建数组(例如,用于LockMany操作)等等

使用对象已有的语言规则来处理所有这些常见和不太常见的用法,可以使语言变得更加简单

如果仅仅有一个锁的关键字,我们不是有更多的类型安全性和更好的意图吗

private object _MyLock = new object();

// someone would now be able to reassign breaking everything
_MyLock = new object();

lock ( _MyLock )
    ...
这与类型安全无关。这是关于线程安全的

有时这意味着在单个
锁中反复运行相同的代码。也许您有一个大型阵列,其中一些操作可能需要交换两个元素,并且您希望确保在交换期间同步。在这种情况下,即使是一个简单的
lock
关键字本身,在幕后为您创建对象,也可能足够好了

有时,您在非常不同的代码集之间共享一个对象。现在您需要多个
lock
部分,这些部分使用公共对象进行协调。在这种情况下,您所谈论的代码似乎是有意义的。让编译器为您创建一个锁对象还不够好,因为不同的
lock
部分不协调,但是您还需要确保公共锁对象是固定的,并且不会以某种方式更改。例如,可能您正在处理一个具有多个线程的数组,并且您有不同的操作,这些操作可能会修改一个共享索引值,该值指示哪个元素被认为是当前的或活动的。每个操作都应该锁定同一个对象


但有时在多组代码中共享多个对象实例(通常是同一类型的)。想想生产者/消费者模式,其中来自不同线程的多个消费者需要协调对共享队列的访问,而消费者本身是多线程的。在这种情况下,单个公共锁对象可以从队列中检索元素,但消费者不同部分中的单个共享对象可能会成为应用程序的瓶颈。相反,您只希望每个活动对象/使用者锁定一次。您需要使用
lock
部分来接受一个变量,该变量指示哪个对象需要保护,而不需要锁定整个数据集。

也许可以让您锁定不同的内容并保存内存,简单到“因为Java就是这样做的,而C#正试图吸引Java程序员”更为相关,将MyLock设置为只读。不要重新分配锁对象。你想要什么类型的“类型安全性”?你需要一些具有标识的东西,你可以使用静态或实例,公共或私有,可能保存在集合中。。。对象已经勾选了所有这些框,“可读性”特性甚至不那么容易设计。你没做完。