網站首頁 編程語言 正文
單例模式也是創建型模式的一種,也是23種設計模式中比較簡單的一種。見名思意,在整個軟件系統中,只有某個類型的一個對象,并且訪問他的地方也只有一個,也就是只有一個全局對象訪問點,這個實例或對象被所有是應用程序所共享;很多可以使用到這樣的功能模塊:比如數據庫連接池對象、打印機對象,因為整個系統中,數據庫的連接只在一個地方連接,打印機在整個系統中也只有一個。這種情況下,單例模式就很大的減少了一個內存的開銷,因為對象的創建是比較消耗內存的,同時因為系統中只有一個實例,比較容易控制,省去了對象創建的過程,更快的進行一個響應,但是在使用單例模式時,由于只有一個實例,所有的線程都可以去使用這個實例,那么不能保證線程的一個安全性,如果要想保證線程的安全性,我們需要使用其他的一些輔助措施。所以對于線程安全的對象我們最好不要使用單例模式,否則可能會降低系統的效率。單例模式只需要一個類就可以實現,自己關聯自己,那么如何實現呢?我們只需要將構造方法定義成私有的,這樣用戶就不能自己去創建這個對象了,然后通過一個靜態方法和靜態變量來存放類的唯一的一個實例。
示例:
創建單例類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 單例模式 { public class Singleton { ////// 1.定義一個私有的構造函數,在類的外部不能被調用 /// private Singleton() { Console.WriteLine("我被創建了!"); } // 2.創建該類的一個靜態變量 private stati c Singleton Instance; // 3.創建返回值為該類型的一個靜態方法 (此方法對外公開) public static Singleton CreateInstance() { if (Instance == null) { Instance = new Singleton(); } return Instance; } } }
主程序調用:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 單例模式 { class Program { static void Main(string[] args) { Singleton s1 = Singleton.CreateInstance(); Singleton s2 = Singleton.CreateInstance(); Console.ReadKey(); } } }
運行結果:
從最后的結果中可以看出,實例只被創建了一次。
在來看看下面的例子:
for (int i = 0; i < 10; i++) { // 執行委托的異步調用 new Action(() => { Singleton singleton = Singleton.CreateInstance(); }).BeginInvoke(null,null); }
結果:
從上面的截圖中看出構造函數被執行了三次。單例模式不是只會構造一次嗎?這里為什么執行了三次呢?因為這里是多線程并發的,10個任務是同時開始的,可能對象不為null的時候有多個線程進入了,所以會執行多次。要解決這種問題,可以使用加鎖。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 單例模式 { public class Singleton { ////// 1.定義一個私有的構造函數,在類的外部不能被調用 /// private Singleton() { Console.WriteLine("我被創建了!"); } // 2.創建該類的一個靜態變量 private static Singleton Instance; // 創建鎖 private static object Singleton_Lock = new object(); // 3.創建返回值為該類型的一個靜態方法 (此方法對外公開) public static Singleton CreateInstance() { lock(Singleton_Lock) // 保證任意時刻只有一個線程才能進入判斷 { if (Instance == null) { Instance = new Singleton(); } } return Instance; } } }
再次運行程序查看結果:
這時只會構造一個對象了。
在來看看懶漢式的單例模式:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 單例模式 { public class SingletonSecond { private SingletonSecond() { Console.WriteLine("我被創建了!"); } private static SingletonSecond Instance = null; ////// 靜態構造函數:由CLR保證在第一次使用這個類之前,調用而且只調用一次 /// static SingletonSecond() { Instance = new SingletonSecond(); } public static SingletonSecond CreateInstance() { return Instance; } } }
在來看看第三種寫法:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 單例模式 { public class SingletonThird { private SingletonThird() { Console.WriteLine("我被創建了!"); } ////// 靜態變量:會在類型第一次使用的時候初始化,而且只初始化一次 /// private static SingletonThird Instance = new SingletonThird(); public static SingletonThird CreateInstance() { return Instance; } } }
代碼下載地址:點擊下載
原文鏈接:https://www.cnblogs.com/dotnet261010/p/7352656.html
相關推薦
- 2022-06-18 C語言深入講解宏的定義與使用方法_C 語言
- 2023-02-07 C#實現加密bat文件的示例詳解_C#教程
- 2023-01-12 Kotlin?Option與Either及Result實現異常處理詳解_Android
- 2023-01-15 rust異步編程詳細講解_Rust語言
- 2022-05-06 詳細談談C語言中動態內存_C 語言
- 2022-07-01 使用Python讀寫多個sheet文件_python
- 2023-03-26 數據結構TypeScript之鄰接表實現示例詳解_其它
- 2022-05-13 python實現簡易圖書管理系統_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同步修改后的遠程分支