M P*_*oet 5 .net c# concurrency visibility thread-safety
这个问题可能看起来有些奇怪,但与可能的可见性问题有关.这个问题的灵感来自Java编程语言(> jdk5)中的一个案例,考虑:
public class InmutableValue {
private int value;
public InmutableValue(int value) {this.value = value;}
public int getValue() {return value;}
}
Run Code Online (Sandbox Code Playgroud)
尽管有相反的信念,但上述课程并非线程安全.在多线程环境中,"value"不保证对其他线程可见.为了使其成为线程安全,我们需要强制实施"先发生"规则.这可以通过标记字段'final'来完成.
这个案例让我想知道.Net运行时是否也是如此.所以举个例子:
public class InmutableValue {
private int value;
public InmutableValue(int value) {this.value = value;}
public int Value { get{return value;}}
}
Run Code Online (Sandbox Code Playgroud)
据我所知,将值字段标记为'readonly'不会给出与'final'对java相同的保证(但我可能非常错误,希望如此).那么我们是否需要将字段标记为"易变"(或使用内存屏障等)以确保其他线程的可见性?或者是否有其他规则可以确保可见性?
无论如何,readonly关键字仅确保该字段将在构造函数中分配,而不是在其他任何地方(在类内部)。
就一般意义上的构造函数而言,构造函数是线程安全的,一旦创建对象将返回相同的值:
static ImmutableValue imv = new ImmutableValue(123);
// thread 1, object is not created
imv.Value; // NullReferenceException, as usually
// thread 2, object is created
imv.Value; //123
// thread 3, object is created
imv.Value; //123
Run Code Online (Sandbox Code Playgroud)
要编辑private字段,您需要使用反射,是的,您需要在此类代码执行期间锁定对象,以保证冻结此时尝试读取值的所有线程。