前言
按需加載對象延遲加載實際是推遲進行建立對象,直到對其調用後才進行建立初始化,延遲(懶加載)的好處是提升系統性能,避免沒必要要的計算以及沒必要要的資源浪費。html
常規有這些狀況:數據庫
示例
建立用戶類安全
public class User { public string Name { get; set; } public int Age { get; set; } public User() { this.Name = "Name"; this.Age = 0; } }
默認狀況下,Lazy<T> 對象是線程安全的。 也就是說,若是構造函數沒有指定線程安全性的類型,該函數建立的 Lazy<T> 對象是線程安全的。 在多線程方案中,訪問線程安全 Lazy<T> 對象的 Value 屬性的第一個線程會爲全部線程上的全部後續訪問對其初始化,且全部線程共享相同的數據。 所以,哪一個線程初始化對象並不重要,爭用條件是良性的。多線程
class Program { static void Main(string[] args) { Lazy<User> user = new Lazy<User>(); ThreadLocal<User> threadLocal = new ThreadLocal<User>(); if (!user.IsValueCreated) Console.WriteLine("The object is not initialized"); Console.WriteLine(user.Value.Name); user.Value.Name = "Name1"; user.Value.Age = 1; Console.WriteLine(user.Value.Name); Console.Read(); } }
對象的線程安全性 | LazyThreadSafetyMode mode 參數 | 布爾 isThreadSafe 參數 | 沒有線程安全性參數 |
---|---|---|---|
徹底線程安全;一次只有一個線程嘗試初始化值。 | ExecutionAndPublication | true | 能夠。 |
非線程安全。 | None | false | 不適用。 |
徹底線程安全;線程爭用以初始化值。 | PublicationOnly | 不適用。 | 不適用。 |
其中IsValueCreated屬性是個Boolean類型,咱們能夠經過此屬性去肯定當前對象有沒有被初始化函數
調用後,進行了建立操做性能
再說說Lazy中幾個構造函數,this
public Lazy (bool isThreadSafe): isThreadSafe 的布爾參數,該方法參數用於指定是否從多線程訪問 Value 屬性。 若是想要僅從一個線程訪問屬性,則傳入 false 以獲取適度的性能優點。 若是想要從多線程訪問屬性,則傳入 true 以指示 Lazy<T> 實例正確處理爭用條件(初始化時一個線程引起異常)。spa
public Lazy (LazyThreadSafetyMode mode):提供線程安全模式。線程
public Lazy (Func<T> valueFactory): lambda 表達式傳遞給新的 Lazy<T> 對象的構造函數。 下一次訪問 Value 屬性將致使新 Lazy<T> 的初始化,而且其 Value 屬性此後會返回已分配給該屬性的新值。code
總結
參考:https://docs.microsoft.com/en-us/dotnet/framework/performance/lazy-initialization
原文出處:https://www.cnblogs.com/yyfh/p/11996509.html