簡體   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