This doubled number cannot be used on volatile fields, is it a safe alternative?
The specified twins cannot be used on volatile fields, is this a safe alternative? Or it might result in a null pointer exception.
public sealed class DoubleStorage
{
public readonly double Value;
public DoubleStorage(double value)
{
this.Value = value;
}
public static readonly DoubleStorage Zero = new DoubleStorage(0);
}
public sealed class Val
{
private volatile DoubleStorage boostResult = DoubleStorage.Zero;
public double ThreadSafeDouble
{
set
{
//is this assignment attomic?
boostResult = new DoubleStorage(value);
}
get
{
//or could this give null pointer exception?
return boostResult.Value;
}
}
}
+3
source to share
2 answers
Yes, link access is atomic.
However, you can just insert a double, you don't need to create a class to encapsulate it:
public sealed class Val {
private volatile object boostResult = 0.0;
public double ThreadSafeDouble {
set {
boostResult = value;
}
get {
return (double)boostResult;
}
}
}
Assigning a double to a variable will create an object that assigns a value to double, then assigns a reference to the variable. Since referential assignment is atomic, it is thread safe.
When unpacking a double, reading a reference from a variable is atomic, so it is thread safe, although reading the double is not atomic. Since the double value in the box is unchanged, the specific value in the box will never change.
Or how about a generic version:
public sealed class ThreadSafe<T> where T : struct {
private volatile object _value;
public ThreadSafe() {
Value = default(T);
}
public ThreadSafe(T value) {
Value = value;
}
public T Value {
get {
return (T)_value;
}
set {
_value = value;
}
}
}
+4
source to share