鉴于双打不能用于易失性领域,这是一种安全的替代方案吗?

时间:2012-04-03 12:32:04

标签: c# volatile

鉴于双打不能用于易失性领域,这是一种安全的选择吗?或者它可能导致空指针异常。

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;
        }
    }
}

2 个答案:

答案 0 :(得分:4)

是的,访问引用是原子的。

但是,你可以只输入double,你不必创建一个类来封装它:

public sealed class Val {

  private volatile object boostResult = 0.0;

  public double ThreadSafeDouble {
    set {
        boostResult = value;
    }
    get {
        return (double)boostResult;
    }
  }
}

为变量赋值为double会创建一个对齐的对象,然后将该引用赋值给变量。由于引用赋值是原子的,因此它是线程安全的。

当取消装箱双,从变量中读取引用是原子的,所以它是线程安全的,尽管读取double不是原子的。由于盒装双精度值是不可变的,因此特定的盒装值永远不会改变。


或者通用版本怎么样:

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;
    }
  }

}

答案 1 :(得分:1)

是的,这个解决方案是安全的,因为引用读取和写入是原子的。