繁体   English   中英

在C#中```线程是否安全?

[英]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()); 线程安全的? 一般的答案是否定的,因为表达式有一个读取和一个写入,这绝对不是原子操作。

可能出错的事情:

  1. 竞争条件读取_Instance :一个线程可以在第二个线程初始化之前将其读取为null 您最终运行CreateInstance()两次。 那是问题吗? 如果是,那么它不是线程安全的。 如果不是,则它可能是线程安全的,从性能的角度来看不是最佳的,但可能是安全的。
  2. 如何同时执行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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM