C#中的``线程安全吗?
简单问题: “C#中的``线程安全吗?,c#,.net,thread-safety,C#,.net,Thread Safety,简单问题: “?”和“?。”和“?:”是线程安全的吗?我能相信他们吗?或者我应该使用其他线程安全解决方案? 例如,此代码: public static T Instance => _Instance ?? (_Instance = CreateInstance()); 线程安全吗??将读取一个在C#中保证是原子的引用(写入也是原子的)。因此,如果你的问题是,你是否可以用C#读写,答案是否定的 现在,这是否使公共静态T实例=>\u实例??(_Instance=CreateInstance(
?
”和“?。
”和“?:
”是线程安全的吗?我能相信他们吗?或者我应该使用其他线程安全解决方案?
例如,此代码:
public static T Instance => _Instance ?? (_Instance = CreateInstance());
线程安全吗?
?
将读取一个在C#中保证是原子的引用(写入也是原子的)。因此,如果你的问题是,你是否可以用C#读写,答案是否定的
现在,这是否使公共静态T实例=>\u实例??(_Instance=CreateInstance())代码>线程安全?一般的答案是否定的,因为表达式有一个读和一个写,这绝对不是一个原子操作
可能出错的事情:
竞态条件读取\u实例
:一个线程可以在第二个线程初始化它之前将其读取为null
。最后运行了两次CreateInstance()
。这是个问题吗?如果是,则它不是线程安全的。如果不是,那么它可能是线程安全的,从性能角度来看不是最优的,但可能是安全的
如何并发执行CreateInstance()
?这种情况安全吗?由于前面的竞争条件,也可能是一个线程在另一个线程退出之前进入CreateInstance
。现在,您的问题不仅仅是CreateInstance
运行两次,而是两次(或更多次)同时运行。安全吗
因此,一般来说,这与CreateInstance()
的安全程度一样安全。由于竞争条件,它不是线程安全的。(例如,线程A检查值,发现值为null,线程B检查值,发现值为null,线程B通过调用CreateInstance()初始化值,线程A通过调用CreateInstance()初始化值。)
单例线程安全初始化的正确方法是使用类,例如:
public T Instance => _instance.Value;
static Lazy<T> _instance = new Lazy<T>(CreateInstance);
public T Instance=>\u Instance.Value;
静态惰性_实例=新惰性(CreateInstance);
其中,CreateInstance()
返回类型为T
的实例。这里的问题不应该是如果??
是线程安全的,而应该是CreateInstance()
是否是。如果假设CreateInstance()
是线程安全的,您仍然需要询问?
表达式是否是线程安全的。@在这两者之间,让我们假设CreateInstance()
是线程安全的。我想重点讨论?
@matthewatson是CreateInstance()
是线程安全的。那?
??。
是一种完全不同的鱼。但不适用于你的例子。同意。它不是线程安全的,特别是如果您不想调用CreateInstance()
两次,竞争条件是一个令人讨厌的条件。我应该在CreateInstance()中使用lock
?@mohammadmimormostafa,它不会有帮助,因为您需要同步对两个条件的访问:??
)和分配(CreateInstance())
)。而是正确地使用Lazy
it all synchronization。@Mohammadmormostafa如果可以从多个线程调用它,并且如果这样做可能导致问题,那么是的-但是我不可能在没有看到它的实现的情况下告诉您。请注意,如果调用它的唯一位置是从Lazy
对象,那么您肯定不需要锁定它。