溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C#設(shè)計(jì)模式學(xué)習(xí)筆記-單例模式

發(fā)布時(shí)間:2020-05-27 15:57:04 來源:網(wǎng)絡(luò) 閱讀:204 作者:skydxd 欄目:編程語言

C#設(shè)計(jì)模式學(xué)習(xí)筆記-單例模式

  在《Design Patterns:Elements of Resuable Object-Oriented Software》中的定義是:Ensure a class only has one instance,and provide a global point of access to。它的主要特點(diǎn)不是根據(jù)客戶程序調(diào)用生成一個(gè)新的實(shí)例,而是控制某個(gè)類型的實(shí)例數(shù)量-唯一一個(gè)。(《設(shè)計(jì)模式-基于C#的工程化實(shí)現(xiàn)及擴(kuò)展》,王翔)。也就是說,單例模式就是保證在整個(gè)應(yīng)用程序的生命周期中,在任何時(shí)刻,被指定的類只有一個(gè)實(shí)例,并為客戶程序提供一個(gè)獲取該實(shí)例的全局訪問點(diǎn)。

  一、經(jīng)典模式:

public class Singleton { private static Singleton instance; private Singleton() { } public static Singleton GetInstance() { if(instance==null) { instance=new Singleton(); } return instance; } }

  解析如下:

  1)首先,該Singleton的構(gòu)造函數(shù)必須是私有的,以保證客戶程序不會通過new()操作產(chǎn)生一個(gè)實(shí)例,達(dá)到實(shí)現(xiàn)單例的目的;

  2)因?yàn)殪o態(tài)變量的生命周期跟整個(gè)應(yīng)用程序的生命周期是一樣的,所以可以定義一個(gè)私有的靜態(tài)全局變量instance來保存該類的唯一實(shí)例;

  3)必須提供一個(gè)全局函數(shù)訪問獲得該實(shí)例,并且在該函數(shù)提供控制實(shí)例數(shù)量的功能,即通過if語句判斷instance是否已被實(shí)例化,如果沒有則可以同new()創(chuàng)建一個(gè)實(shí)例;否則,直接向客戶返回一個(gè)實(shí)例。

  在這種經(jīng)典模式下,沒有考慮線程并發(fā)獲取實(shí)例問題,即可能出現(xiàn)兩個(gè)線程同時(shí)獲取instance實(shí)例,且此時(shí)其為null時(shí),就會出現(xiàn)兩個(gè)線程分別創(chuàng)建了instance,違反了單例規(guī)則。因此,需對上面代碼修改。

  二、多線程下的單例模式

  1、Lazy模式

public class Singleton { private static Singleton instance; private static object _lock=new object(); private Singleton() { } public static Singleton GetInstance() { if(instance==null) { lock(_lock) { if(instance==null) { instance=new Singleton(); } } } return instance; } }

  上述代碼使用了雙重鎖方式較好地解決了多線程下的單例模式實(shí)現(xiàn)。先看內(nèi)層的if語句塊,使用這個(gè)語句塊時(shí),先進(jìn)行加鎖操作,保證只有一個(gè)線程可以訪問該語句塊,進(jìn)而保證只創(chuàng)建了一個(gè)實(shí)例。再看外層的if語句塊,這使得每個(gè)線程欲獲取實(shí)例時(shí)不必每次都得加鎖,因?yàn)橹挥袑?shí)例為空時(shí)(即需要?jiǎng)?chuàng)建一個(gè)實(shí)例),才需加鎖創(chuàng)建,若果已存在一個(gè)實(shí)例,就直接返回該實(shí)例,節(jié)省了性能開銷。

  2、餓漢模式

  這種模式的特點(diǎn)是自己主動(dòng)實(shí)例。

public sealed class Singleton { private static readonly Singleton instance=new Singleton(); private Singleton() { } public static Singleton GetInstance() { return instance; } }
  上面使用的readonly關(guān)鍵可以跟static一起使用,用于指定該常量是類別級的,它的初始化交由靜態(tài)構(gòu)造函數(shù)實(shí)現(xiàn),并可以在運(yùn)行時(shí)編譯。在這種模式下,無需自己解決線程安全性問題,CLR會給我們解決。由此可以看到這個(gè)類被加載時(shí),會自動(dòng)實(shí)例化這個(gè)類,而不用在第一次調(diào)用GetInstance()后才實(shí)例化出唯一的單例對象。
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI