I ran into some singleton code today in our codebase and I wasn't sure if the following was thread-safe:
public static IContentStructure Sentence{
get {
return _sentence ?? (_sentence = new Sentence());
}
}
This statement is equivalent to:
if (_sentence != null) {
return _sentence;
}
else {
return (_sentence = new Sentence());
}
I believe that ?? is just a compiler trick and that the resulting code is still NOT atomic. In other words, two or more threads could find _sentence to be null before setting _sentence to a new Sentence and returning it.
To guarantee atomicity, we'd have to lock that bit of code:
public static IContentStructure Sentence{
get {
lock (_sentence) { return _sentence ?? (_sentence = new Sentence()); }
}
}
Is that all correct?
The carbon atom has four valence electrons. It shares two electrons with one oxygen atom and two with another oxygen atom. So the total number of atoms in a molecule of carbon dioxide is 3. Hence the atomicity of carbon dioxide is 3.
Atomicity of Phosphorus is 4.
Let us now take example of Carbon dioxide molecule ($C{O_2}$) , in Carbon dioxide ($C{O_2}$) there is one atom of carbon ( C ) and two atoms of oxygen ( O ) So atomicity of Carbon dioxide molecule ( $C{O_2}$) will be 2 + 1 = 3 . So the answer to this question is 8 that is atomicity of ethane ${C_2}{H_6}$.
The atomicity of oxygen is 2.
I ran into some singleton code today in our codebase
Do you have such obfuscated code throughout your codebase? This code does the same thing:
if (_s == null)
_s = new S();
return _s;
and is about a thousand times easier to read.
I believe that ?? is just a compiler trick and that the resulting code is still NOT atomic
You are correct. C# makes the following guarantees of atomicity:
Reads and writes of the following data types are atomic: bool, char, byte, sbyte, short, ushort, uint, int, float, and reference types. In addition, reads and writes of enum types with an underlying type in the previous list are also atomic. Reads and writes of other types, including long, ulong, double, and decimal, as well as user-defined types, are not guaranteed to be atomic. Aside from the library functions designed for that purpose, there is no guarantee of atomic read-modify-write, such as in the case of increment or decrement.
The null coalescing operator is not on that list of guarantees.
To guarantee atomicity, we'd have to lock that bit of code:
lock (_sentence) { return _sentence ?? (_sentence = new Sentence()); } } }
Good heavens no. That crashes immediately!
The correct thing to do is one of:
Lazy<T>
class.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With