有一个类似的类:
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
}
基本上问题是:如果我锁定其成员,则包含类会自动锁定,或者它根本不起作用。
请不告诉我:
你应该使用一个锁定对象或互斥锁,它可能是一个解决方案,但它与问题无关。
答案 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”)违反了这条准则:
如果可以公开访问实例,则
- 如果MyType可公开访问,则
lock(this)是一个问题。
lock(typeof(MyType))是一个问题。
lock(“myLock”)是一个问题,因为进程中使用相同字符串的任何其他代码都将共享同一个锁。
最佳做法是定义要锁定的私有对象,或私有静态对象变量以保护所有实例共有的数据。