鉴于双打不能用于易失性领域,这是一种安全的选择吗?或者它可能导致空指针异常。
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;
}
}
}
答案 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)
是的,这个解决方案是安全的,因为引用读取和写入是原子的。