锁定在代码执行期间可能更改的对象
本文关键字:对象 代码 执行期 锁定 | 更新日期: 2023-09-27 18:18:20
假设有一个线程锁定了一个对象引用
线程#1
lock(myObj) { ... }
后面的代码我有myObj = new XYZObj();
,然后线程#2锁定它
lock(myObj) { ... }
如果对象引用改变了,这段代码是线程安全的吗?当对象引用发生变化时,第一个锁仍然有效吗?
锁作用于实例,而不是变量。lock
语句将保留它自己对实例的引用,因此它只会退出您输入的实例。
规格说明:
是精确等价的,其中x是引用类型的表达式
System.Threading.Monitor.Enter(x); try { ... } finally { System.Threading.Monitor.Exit(x); }
除了x只求值一次。
如果您在两个锁之间重新分配变量,您将在两个不同的实例上获得两个有效的锁。
但是,一般情况下,你不应该这样做;这是一个微妙的错误和竞争条件的配方。您应该只锁定专用的只读锁对象。
No。它们都将锁定不同的对象。
根据MSDN
最佳实践是定义一个要锁定的私有对象,或者一个私有的静态对象变量,用于保护所有实例共有的数据。
这个代码是线程安全的吗
语句lock(myObj) { ... }
是安全的,直到一个新的对象引用被分配给myObj
变量。附加:另外,只有当线程之间共享的数据在一个对象的锁内使用非原子变化时,只有在在同一个对象的锁内使用非原子变化时才安全。
因此,每次为myObj
输入锁时,实际引用的对象是用于该锁的对象,而不是您的变量。如果您将变量更改为引用一个新对象,那么您将有效地将不同的对象锁定在不同的锁中,这显然不是您想要的。但是,下次再回到第一个锁时,第一个和第二个锁对象可能又同步了,所以它又安全了。也许!