在 class 中锁定 class

Lock class inside a class

有一个class像这样:

public class A{
    public B classB { get; set; }
    ...
}

A 在某处实例化为 classA.

classA.classB 由我无法控制的代码设置和修改,这些代码可能在不同的线程上。

现在我想在我的线程上修改classA.classB。

我需要1:

lock(classA) lock(classA.classB) {
//my codes that modifies classA.classB
}

2:

lock(classA.classB){
//my codes that modifies classA.classB
}

Basically the question is: Is containing class automatically locked if I lock its members, or it doesn't work like that at all.

不要告诉我:

那么你应该使用锁定对象或互斥体,它可能是一个解决方案,但它与问题无关。

我认为您对 lock 语句的使用感到困惑。它确保只有一个线程在一段代码中,为此,它使用了一些可以发出信号或不发出信号的东西(将其视为布尔值)。

lock(anobjectreference)
{
    .... code ....
}

具有相同对象引用的两个线程不能同时在锁中。 anobjectreference 只是一个基于引用(内存中的指针)的标识符,用于允许线程进入 o 而不是锁定。

有一个最佳实践表明您应该锁定专门为锁定而创建的对象:

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement

In general, avoid locking on a public type, or instances beyond your code's control. The common constructs lock (this), lock (typeof (MyType)), and lock ("myLock") violate this guideline:

  • lock (this) is a problem if the instance can be accessed publicly.

  • lock (typeof (MyType)) is a problem if MyType is publicly accessible.

  • lock("myLock") is a problem because any other code in the process using the same string, will share the same lock.

Best practice is to define a private object to lock on, or a private static object variable to protect data common to all instances.

Is containing class automatically locked if I lock its members, or it doesn't work like that at all.

它根本不是那样工作的。 lock 除了检查是否非常相同的 object 引用已经被锁定,等到它不是然后锁定它,当块结束时删除锁。它 暗示 除了一点信息之外的任何其他内容 :它是否被锁定。

具体来说,它不会锁定任何成员、类型或其他东西。它 完全 您提供的 object 锁定。锁不会做任何事情,除非在询问时给出锁已经存在的信息。它不会阻止代码访问 object、读取、写入、处置或其他任何内容。

你的问题读起来有点像你期望 lock 除了与其他 lock 块交互之外还有效果。它没有。

所以你应该有一个完全独立的 object 到 lock,因为如果你使用一个也用于其他目的并且公开可用的 object,可能会发生不好的事情。由于使用 this 或 class object 没有任何好处,因为 lock 没有做任何额外的事情,如果不遵循最佳实践指南,您真的没有任何好处。

classA.classB is set and modified by codes I have no control of, those codes may be on different threads.

Now I want to modify classA.classB on the my thread.

你真……很尴尬。对此没有解决方案。你不能 lock 这样的事情。这不是 one-sided。如果其他代码没有使用您使用的同一把锁……他们不会关心您的锁。 lock 就像一个信号。一道红光。你随便放红灯,别人driver不知道或者不在乎,你也没办法。

您唯一的选择是控制 classB 实施并确保它在内部 thread-safe。