您好,登錄后才能下訂單哦!
在《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; } }
免責(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)容。