網站首頁 編程語言 正文
什么是單例模式?
這里我就不做過多的解釋了, 畢竟關于Singleton的資料實在是太多太多了。點擊這里
簡單的思路就是, 創建對象單例的動作轉移到另外的行為上面, 利用一個行為去創建對象自身, 如下:
public class Singleton { private Sington() { } private static Singleton _Singleton = null; public static Singleton CreateInstance() { if (_Singleton == null) { Console.WriteLine("被創建"); _Singleton = new Singleton(); } return _Singleton; } }
這樣寫看上去是沒有問題, 但是有沒有那種可能, 同時兩個動作都判斷這個對象為空, 那么這個對象就會被創建2次?是的, 多線程中, 這樣是無法保證單例。
就像這樣, 同時創建多個線程去創建這個對象實例的時候, 會被多次創建, 這個時候, 對代碼改進一下。
public class Singleton { private Sington() { } private static Singleton _Singleton = null; private static object Singleton_Lock = new object(); //鎖同步 public static Singleton CreateInstance() { lock (Singleton_Lock) { Console.WriteLine("路過"); if (_Singleton == null) { Console.WriteLine("被創建"); _Singleton = new Singleton(); } } return _Singleton; } }
調試代碼:
TaskFactory taskFactory = new TaskFactory(); List<Task> taskList = new List<Task>(); for (int i = 0; i < 5; i++) { taskList.Add(taskFactory.StartNew(() => { Singleton singleton = Singleton.CreateInstance(); })); }
結果:
上面, 我們創建了多個線程,同時去創建這個對象的實例, 在第二次,對象命名已經被創建了, 盡管只創建了一次滿足了我們的需求, 但是我們已知對象被創建了, 還需要進來做不必要的動作嗎?
我們都知道, 同步鎖為了達到預期的效果, 也是損耗了性能的, 那么下面的輸出, 很顯然是沒必要的動作, 所以我們優化一下。
public class Singleton { private static Singleton _Singleton = null; private static object Singleton_Lock = new object(); public static Singleton CreateInstance() { if (_Singleton == null) //雙if +lock { lock (Singleton_Lock) { Console.WriteLine("路過。"); if (_Singleton == null) { Console.WriteLine("被創建。"); _Singleton = new Singleton(); } } } return _Singleton; } }
結果:
很顯然, 這樣達到了我們的預期, 對象在被創建后, 就沒必要做多余的行為。
利用靜態變量實現單例模式
public sealed class Singleton { private Singleton() { } private static readonly Singleton singleInstance = new Singleton(); public static Singleton GetInstance { get { return singleInstance; } } }
是不是覺得很優雅, 利用靜態變量去實現單例, 由CLR保證,在程序第一次使用該類之前被調用,而且只調用一次
PS: 但是他的缺點也很明顯, 在程序初始化后, 靜態對象就被CLR構造了, 哪怕你沒用。
利用靜態構造函數實現單例模式
public class SingletonSecond { private static SingletonSecond _SingletonSecond = null; static SingletonSecond() { _SingletonSecond = new SingletonSecond(); } public static SingletonSecond CreateInstance() { return _SingletonSecond; } }
靜態構造函數:只能有一個,無參數的,程序無法調用 。
同樣是由CLR保證,在程序第一次使用該類之前被調用,而且只調用一次。同靜態變量一樣, 它會隨著程序運行, 就被實例化, 同靜態變量一個道理。
單例模式中的延遲加載
延遲加載或延遲加載是一種設計模式,或者您可以說這是一個概念,通常用于將對象的初始化延遲到需要時。因此,延遲加載的主要目標是按需加載對象,或者您可以根據需要說出對象。
作為 .NET Framework 4.0 的一部分引入的惰性關鍵字為惰性初始化(即按需對象初始化)提供了內置支持。如果要使對象(如 Singleton)以延遲初始化,則只需將對象的類型(單例)傳遞給lazy關鍵字,如下所示。
private static readonly Lazy<Singleton> Instancelock = new Lazy<Singleton>(() => new Singleton());
public sealed class Singleton { private Singleton() {} private static readonly Lazy<Singleton> Instancelock = new Lazy<Singleton>(() => new Singleton()); public static Singleton GetInstance { get { return Instancelock.Value; } } }
原文鏈接:https://www.cnblogs.com/zh7791/p/7930342.html
相關推薦
- 2022-07-12 Handler機制相關流程
- 2022-12-23 Kotlin擴展函數與運算符重載超詳細解析_Android
- 2022-05-06 input 限制輸入 小數點后兩位
- 2022-07-18 Linux文件系統和日志分析
- 2023-03-27 Android?Framework原理Binder驅動源碼解析_Android
- 2022-10-27 Kotlin?Flow操作符及基本使用詳解_Android
- 2022-09-29 docker啟動rabbitmq以及使用方式詳解_docker
- 2022-04-09 一起來了解python的if流程控制_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支