5

可能重复:
C# 线程中的只读字段是否安全?

一个很简单的程序

private readonly string _data1;
private readonly int _data2;
private readonly MyAnotherClass _data3;

public MyClass(string data1, int data2, MyAnotherClass data3)
{
    _data1 = data1;
    _data2 = data2;
    _data3 = data3;
}

_data1, _data2 and _data3线程安全吗?

4

4 回答 4

8

只读变量保证在被访问之前被初始化。在对象完全分配之前,在对象的构造过程中分配初始值。

变量初始化器被转换为赋值语句,并且这些赋值语句在基类实例构造函数的调用之前执行。这种排序确保所有实例字段在执行任何有权访问该实例的语句之前由其变量初始化程序初始化

参考:C# Spec,10.11.3 构造函数执行(强调我的)

对只读字段的赋值只能作为字段声明的一部分或在同一类的构造函数中发生

参考:C# 规范,1.6.5 字段

因此,该值将在任何线程可用之前设置,并且不会更改,因此它是线程安全的。

于 2012-11-13T02:55:45.253 回答
4

是的,它们是因为一旦构建了类,任何软件都无法更改它们。

编辑

虽然数据字段是线程安全的,但 _data3 的内容不是线程安全的。不同的线程可以“同时”修改 _data3。

于 2012-11-13T02:55:49.473 回答
1

Joh Skeets 在Is a readonly field in C# thread safe?给出了大部分答案 - 对于不可变类型(如int/ string),它是线程安全的。

如果自定义类型不是不可变的,引用本身将是线程安全的,但readonly不保证对象内容的任何内容。所以_data3对象的所有属性都需要有自定义的线程安全保护。

于 2012-11-13T03:05:15.173 回答
0

只要您以后不更改它们,是的。

编辑:

class Class1
{

    readonly string bigbuddy;

    public Class1()
    {

        bigbuddy = "1";

        Thread thread1 = new Thread(SomeThread);
        thread1.Start(this);

        Thread.Sleep(1000);

        bigbuddy = "2";

        Thread thread2 = new Thread(SomeThread);
        thread2.Start(this);

    }

    public void SomeThread(object state) {

        Class1 class1 = (Class1)state;

        Debug.WriteLine(class1.bigbuddy);

    }


}

采用:

 Class1 asd = new Class1();

输出:

1
The thread '<No Name>' (0xe0c) has exited with code 0 (0x0).
2
The thread '<No Name>' (0x129c) has exited with code 0 (0x0).
于 2012-11-13T02:55:38.817 回答