我的一个类有一个 Guid 类型的属性。此属性可以由多个线程同时读取和写入。我的印象是对 Guid 的读写不是原子的,因此我应该锁定它们。
我选择这样做:
public Guid TestKey
{
get
{
lock (_testKeyLock)
{
return _testKey;
}
}
set
{
lock (_testKeyLock)
{
_testKey = value;
}
}
}
(在我的类中,对 Guid 的所有访问也是通过该属性完成的,而不是直接访问 _testKey。)
我有两个问题:
(1) 真的有必要像那样锁定 Guid 以防止读取撕裂吗? (我很确定它是。)
(2) 这是进行锁定的合理方法吗?还是我需要像下面这样:
get
{
Guid result;
lock (_testKeyLock)
{
result = _testKey;
}
return result;
}
[编辑] 这篇文章确实确认 Guids 会遭受读取撕裂:http://msdn.microsoft.com/en-us/magazine/jj863136.aspx
最佳答案
1:是;如果您有一个线程读取和一个写入,则可以防止值被撕裂; Guid
不保证是原子的
2: "like the following": 它们实际上是一样的;在 IL 级别,您不能 ret
来自 try
/catch
block ,因此编译器通过以下方式实现您的第一个示例引入一个局部变量,就像在你的第二个例子中一样。
另一种方法可能是装箱;引用是原子的:
object boxedTestKey;
public Guid TestKey
{
get { return (Guid)boxedTestKey; }
set { boxedTestKey = value; }
}
不需要锁定,但盒子的开销很小。
关于c# - 使 Guid 属性线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14647811/