在类中锁定类

时间:2017-12-15 02:47:04

标签: c# multithreading thread-safety member

有一个类似的类:

const makeImages = (count=10, startIndex=0) => {
  const width = 100;
  const imagesArray = _.times(count, (index) => {
    const height = 100 + Math.round(Math.random() * 200);
    return {
      key: startIndex+index,
      src: `http://placehold.it/${width}x${height}/${((1<<24)*Math.random()|0).toString(16)}/fff?text=${startIndex+index}`,
    }
  });

  return imagesArray;
};

A在某处实例化为classA。

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

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

我需要 1

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

2

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

基本上问题是:如果我锁定其成员,则包含类会自动锁定,或者它根本不起作用。

告诉我:

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

2 个答案:

答案 0 :(得分:2)

  

如果我锁定其成员,则包含类会自动锁定,或者它根本不起作用。

它根本不起作用。除了检查相同的对象引用是否已被锁定外,lock不执行任何等到它没有然后锁定它,在块结束时移除锁定。除了那一点信息之外,暗示其他:是锁定还是不锁定。

具体来说,它不会锁定任何成员,类型或其他东西。它将完全锁定您提供的对象。并且锁定不会执行任何操作,除非在询问时提供已存在锁定的信息。它不会阻止代码访问对象,读取,写入,处置等等。

您的问题有点像您期望lock除了与其他lock块进行交互之外还有效果。它不是。

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

  

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

     

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

你是......处于不利地位。没有解决方案。你不能lock那样的东西。这不是片面的。如果其他代码没有使用相同的锁,你就会......他们不会关心你的锁。 lock就像一个信号。红灯。您可以在任何地方放置红灯,如果其他司机不知道或不关心,您无能为力。

您唯一的选择是控制classB实现并确保它在内部是线程安全的。

答案 1 :(得分:0)

我认为您对使用lock语句感到困惑。它确保只有一个线程在代码的一个部分内,为了做到这一点,它使用了可以发信号通知的东西(将其视为布尔值)。

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

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

有一种最佳做法,即您应该锁定专门为锁定而创建的对象:

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

  

一般情况下,避免锁定公共类型或超出您的实例   代码的控制。常见的构造锁定(this),锁定(typeof   (MyType))和lock(“myLock”)违反了这条准则:

     
      如果可以公开访问实例,则
  • lock(this)是一个问题。

  •   如果MyType可公开访问,则
  • lock(typeof(MyType))是一个问题。

  •   
  • lock(“myLock”)是一个问题,因为进程中使用相同字符串的任何其他代码都将共享同一个锁。

  •   
     

最佳做法是定义要锁定的私有对象,或私有静态对象变量以保护所有实例共有的数据。