[英]Is `??` thread safe in C#?
简单的问题:“ ??
”和“ ?.
”和“ ? :
”是否是线程安全的? 我能相信他们吗? 或者我应该使用其他线程安全解决方案? 例如这段代码:
public static T Instance => _Instance ?? (_Instance = CreateInstance());
是线程安全的吗?
??
将读取一个在C#中保证是原子的引用(写也是)。 因此,如果你的问题是,你可以在C#中撕裂引用读取或写入,答案是否定的。
现在,这会使public static T Instance => _Instance ?? (_Instance = CreateInstance());
public static T Instance => _Instance ?? (_Instance = CreateInstance());
线程安全的? 一般的答案是否定的,因为表达式有一个读取和一个写入,这绝对不是原子操作。
可能出错的事情:
_Instance
:一个线程可以在第二个线程初始化之前将其读取为null
。 您最终运行CreateInstance()
两次。 那是问题吗? 如果是,那么它不是线程安全的。 如果不是,则它可能是线程安全的,从性能的角度来看不是最佳的,但可能是安全的。 CreateInstance()
? 这种情况安全吗? 由于之前的竞争条件,一个线程也可能在另一个线程退出之前进入CreateInstance
。 现在你的问题不是CreateInstance
运行两次,而是两个(或更多)并发运行。 这样安全吗? 所以一般来说,这和CreateInstance()
安全性一样安全。
由于竞争条件,它不是线程安全的。 (例如,线程A检查值,发现它为空,线程B检查值,发现它为空,线程B通过调用CreateInstance()初始化值,线程A通过调用CreateInstance()来初始化值。)
单例的线程安全初始化的正确方法是使用Lazy<T>
类,例如:
public T Instance => _instance.Value;
static Lazy<T> _instance = new Lazy<T>(CreateInstance);
其中CreateInstance()
返回类型为T
的实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.