给定替身可以';不能用于挥发性领域,这是一种安全的替代方案吗
本文关键字:一种 安全 方案 替身 挥发性 用于 不能 | 更新日期: 2023-09-27 18:29:55
鉴于doubles不能在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;
}
}
}
是的,访问引用是原子的。
然而,您可以将double框起来,不必创建一个类来封装它:
public sealed class Val {
private volatile object boostResult = 0.0;
public double ThreadSafeDouble {
set {
boostResult = value;
}
get {
return (double)boostResult;
}
}
}
为变量指定一个double将创建一个对象,该对象将double框起来,然后为变量指定引用。由于引用赋值是原子的,所以它是线程安全的。
当取消装箱double时,从变量中读取引用是原子的,因此即使读取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;
}
}
}