From C# - The C# Memory Model in Theory and Practice, Part 1 & 2
https://msdn.microsoft.com/en-us/magazine/jj863136.aspx
https://msdn.microsoft.com/en-us/magazine/jj883956.aspx
... the compiler and the hardware can subtly transform a program’s memory operations in ways that don’t affect the single-threaded behavior, but might affect the multithreaded behavior.
It means C# compilers can set an object reference before its constructor finish. Is readonly
sufficient to write immutable objects for multi-thread?
In Java, when a field is declared as final
, it is ready before the parent object reference is observable, stated in Java Language Specification 17.5
https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.5
when the object is seen by another thread, that thread will always see the correctly constructed version of that object's final fields. It will also see versions of any object or array referenced by those final fields that are at least as up-to-date as the final fields are.
Do readonly fields work the same as final in Java? Are the two pieces of code below thread-safe?
1st piece
public class A
{
private readonly string s1;
public A()
{
s1 = "abc";
}
public string S1 => s1;
// or public string S1 { get; }
}
public class B
{
private volatile A a = null; // a will not be set to null anymore
public void SomeFunction()
{
Task.Run(() =>
{
while (a == null) ;
Console.WriteLine(a.S1);
});
a = new A();
}
}
2nd piece
public class A
{
private readonly string s1;
public A()
{
s1 = "abc";
Thread.MemoryBarrier();
}
public string S1 => s1;
}
public class B
{
private A a = null;
public void SomeFunction()
{
Task.Run(() =>
{
while (a == null) ;
Console.WriteLine(a.S1);
});
a = new A();
}
}
Alternatively, A
can be in this form
public class A
{
public A()
{
S1 = "abc";
}
public string S1 { get; }
}
Can C# compilers inline the object construction like this?
public class B
{
private viotile A a = null;
public void SomeFunction()
{
Task.Run(() =>
{
while (a == null) ;
Console.WriteLine(a.S1);
});
a = new memory for A
a.s1 = "abc";
}
}
C# here means .Net Framework, .Net Core, ECMA and/or other variances
Reference Is it possible to observe a partially-constructed object from another thread?