C# 中的只读字段线程安全吗?
C# 中的 readonly
字段线程安全吗?
public class Foo
{
private readonly int _someField;
public Foo()
{
_someField = 0;
}
public Foo(int someField)
{
_someField = someField;
}
public void SomeMethod()
{
doSomething(_someField);
}
}
浏览过一些帖子:
- 在 C# 中将字段标记为只读有什么好处? - JaredPar 建议只读字段一旦构造出来就是不可变的,因此是安全的。
- 只读字段和线程安全,建议如果施工人员做大量工作,就会存在一些风险。
那么,如果像上面的代码那样使用 readonly 字段,并且构造函数很轻,那么它是线程安全的吗?如果 _someField
是引用类型(例如字符串数组)怎么办?
Is a readonly
field in C# thread safe?
public class Foo
{
private readonly int _someField;
public Foo()
{
_someField = 0;
}
public Foo(int someField)
{
_someField = someField;
}
public void SomeMethod()
{
doSomething(_someField);
}
}
Have gone through some posts:
- What are the benefits to marking a field as readonly in C#? - JaredPar suggests that readonly fields once constructed are immutable and hence safe.
- Readonly Fields and Thread Safety, suggests that there is some risk if constructors do a lot of work.
So, if the readonly
field is used as in the code above, and constructors are light, is it thread-safe? What if _someField
is a referrence type (e.g. an array of strings)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的 - 您的代码不会在任一构造函数中公开
this
,因此在完全构造该对象之前,其他代码都无法“查看”该对象。 .NET 内存模型(从 .NET 2 开始)在每个构造函数的末尾都包含一个写屏障(IIRC - 搜索 Joe Duffy 的博客文章以获取更多详细信息),因此到目前为止,不存在另一个线程看到“陈旧”值的风险据我所知。我个人通常仍然会使用属性,作为将实现与 API 分离的一种方式,但从线程安全的角度来看,这很好。
Yes - your code doesn't expose
this
within either constructor, so no other code can "see" the object before it's been fully constructed. The .NET memory model (as of .NET 2) includes a write barrier at the end of every constructor (IIRC - search Joe Duffy's blog posts for more details) so there's no risk of another thread seeing a "stale" value, as far as I'm aware.I'd personally still usually use a property instead, as a way of separating implementation from API, but from a thread-safety point of view it's fine.
这取决于该领域的情况。
从只读字段或任何小于字长的字段(包括所有引用类型)读取是原子操作。
但是,只读字段内的对象可能是也可能不是线程安全的。
That depends what's in the field.
Reading from a readonly field, or from any field that is smaller than the word length (including all reference types) is an atomic operation.
However, the object inside the readonly field may or may not be thread-safe.
不看你的例子,但一般来说,它取决于只读应用的内容,例如,如果字典被声明为只读,你仍然可以更新键值对
Not looking at your example but in general it depends what is readonly applied to, for example if dictionary is declared readonly you can still update keyvalue pairs