锁定在代码执行期间可能更改的对象

gsb*_*gsb 5 c# multithreading

假设我有一个锁定对象引用的线程

线程#1

lock(myObj) { ... }
Run Code Online (Sandbox Code Playgroud)

后来我的代码 myObj = new XYZObj();

然后线程#2锁定它

lock(myObj) { ... }
Run Code Online (Sandbox Code Playgroud)

如果对象引用已更改,此代码是否是线程安全的?当对象引用更改时,第一个锁仍然有效?

SLa*_*aks 7

锁定适用于实例,而不是变量.
lock语句将保留对该实例的引用,以便它只退出您输入的实例.

规范说:

其中x是引用类型的表达式,恰好相当于

System.Threading.Monitor.Enter(x);
try {
   ...
}
finally {
   System.Threading.Monitor.Exit(x);
}
Run Code Online (Sandbox Code Playgroud)

除了x只评估一次.

如果在两个锁之间重新分配变量,则会在两个不同的实例上获得两个有效锁.

但是,一般来说,你永远不应该这样做; 这是一个微妙的错误和竞争条件的配方.
您应该只锁定专用的只读锁定对象.