摘要:?jiǎn)卫J降膶?shí)際應(yīng)用到了看一下單例模式廬山真面目的時(shí)候了,首先通過一段簡(jiǎn)單的代碼看一下其大體結(jié)構(gòu)。單例模式在中有那些應(yīng)用呢中有很多系統(tǒng)級(jí)別的全局變量,如時(shí)間,輸入法,賬戶,狀態(tài)欄等等類,類類等等。
目錄
單例模式
為什么使用單例模式
單例模式實(shí)際應(yīng)用
單例模式這個(gè)設(shè)計(jì)模式應(yīng)該算是我最早接觸到一個(gè),也是從那個(gè)時(shí)候知道有一種東西叫設(shè)計(jì)模式,看到這種代碼結(jié)構(gòu),有種將好的東西通過某種精美的包裝進(jìn)行包裝一樣,似錦上添花。
單例模式:單例模式中有一個(gè)單例類的結(jié)構(gòu),來保證系統(tǒng)中,該類只能夠被實(shí)例化一個(gè),通過這種方式控制系統(tǒng)中實(shí)例的個(gè)數(shù),同時(shí)易于外界訪問。
為什么使用單例模式對(duì)于緩存,數(shù)據(jù)庫(kù)連接,網(wǎng)絡(luò)請(qǐng)求隊(duì)列等,資源消耗比較大的,通常我們只是需要一個(gè)實(shí)例,來減少資源的消耗。
為什么不實(shí)用靜態(tài)全局變量來進(jìn)行控制呢?
通過靜態(tài)全局變量持有一個(gè)我們創(chuàng)建的實(shí)例,然后對(duì)這個(gè)實(shí)例進(jìn)行一些操作不也是可以保證單例嗎?這種方式似乎要比多出一個(gè)設(shè)計(jì)模式去改變類的結(jié)構(gòu)方便的多,但是我們卻不會(huì)這樣去做,原因就是
當(dāng)我們?cè)O(shè)置一個(gè)全局的變量在系統(tǒng)中,其會(huì)導(dǎo)致出現(xiàn)命名空間污染現(xiàn)象,導(dǎo)致我們?cè)谝恍┮玫倪^程中,出現(xiàn)了將全局變量作為局部變量使用的情況,
同時(shí)如果我們對(duì)于靜態(tài)全局變量如果不加鎖的話,很容易在多線程操作的過程中帶來同步上的一些問題,
最后一個(gè)原因就是如果我們將其作為一個(gè)靜態(tài)全局變量使用,那么我們就無法實(shí)現(xiàn)一個(gè)惰性創(chuàng)建實(shí)例,對(duì)于過于消耗資源的實(shí)例,通過惰性創(chuàng)建,我們將其拖延至使用時(shí)創(chuàng)建,而不會(huì)過早的消耗資源。
單例模式的實(shí)際應(yīng)用到了看一下單例模式廬山真面目的時(shí)候了,首先通過一段簡(jiǎn)單的Java代碼看一下其大體結(jié)構(gòu)。
public class Singleton{ private static Singleton mSingleton = null; private Singleton(){ } public static Singleton getInstance(){ if(mSingleton==null) mSingleton = new Singleton(); return mSingleton; } }
上面是一個(gè)簡(jiǎn)單單例模式的示范代碼,通過這個(gè)代碼,我們可以看出單例類的構(gòu)造方法是私有方法,也就是該類我們沒有辦法通過new得到的,只能夠通過靜態(tài)的getInstance()方法得到。但是對(duì)于多線程問題,如果有多個(gè)線程在執(zhí)行這個(gè)方法,那么可能就會(huì)有多個(gè)實(shí)例被創(chuàng)建出來,如何應(yīng)對(duì)這個(gè)問題呢?
1.對(duì)該代碼區(qū)域進(jìn)行同步
public class Singleton{ private static Singleton mSingleton = null; private Singleton(){ } public synchronized Singleton static getInstance(){ if(mSingleton==null) mSingleton = new Singleton(); return mSingleton; } }
當(dāng)我們對(duì)代碼塊進(jìn)行加鎖之后,一個(gè)線程就要等到另一個(gè)線程結(jié)束之后,才可以繼續(xù)執(zhí)行該區(qū)域代碼,但是當(dāng)我們對(duì)一個(gè)代碼區(qū)域進(jìn)行加鎖之后,我們的代碼效率就會(huì)降低100倍。對(duì)這個(gè)代碼區(qū)域進(jìn)行同步之后,每當(dāng)我們執(zhí)行這塊代碼,都將會(huì)出現(xiàn)一個(gè)等待。
2.急切創(chuàng)建實(shí)例,而不是采用惰性創(chuàng)建
public class Singleton{ private static Singleton mSingleton = new Singleton(); private Singleton(){ } public synchronized Singleton static getInstance(){ return mSingleton; } }
通過急切創(chuàng)建在對(duì)類進(jìn)行初始化的時(shí)候就實(shí)例化了類,就不會(huì)出現(xiàn)多個(gè)線程競(jìng)爭(zhēng)的問題,但是會(huì)導(dǎo)致的問題是如果創(chuàng)建實(shí)例消耗過大的時(shí)候就會(huì)出現(xiàn)提前消耗資源的問題。因此我們常采用的一種方法是雙重加鎖法。
3.雙重檢查加鎖
public class Singleton{ private static Singleton mSingleton = null; private Singleton(){ } public Singleton static getInstance(){ if(mSingleton==null){ synchronized (Singleton.class){ if(mSingleton==null) mSingleton = new Singleton(); } } return mSingleton; } }
這種方式對(duì)于加鎖不是對(duì)整個(gè)方法進(jìn)行加鎖,而是判斷當(dāng)這個(gè)單例未被初始化之后,才對(duì)這個(gè)實(shí)例的初始化區(qū)域進(jìn)行一個(gè)同步,在同步的過程中在進(jìn)行一個(gè)是否實(shí)例化的判斷。即所謂的雙重檢查。課有疑問的在于,我們已經(jīng)進(jìn)入了同步區(qū)域了,為什么還要對(duì)其做一個(gè)判斷呢?就是當(dāng)兩個(gè)線程同時(shí)越過了第一個(gè)判斷之后,如果我們?cè)谕椒椒ㄖ袥]有對(duì)與實(shí)例的判斷,這個(gè)時(shí)候,我們就有可能出現(xiàn)實(shí)例被創(chuàng)建兩次的情況。
綜上所述:綜合效率,資源消耗等來看,通過雙重檢查加鎖的方式來創(chuàng)建最為方便。
單例模式在android中有那些應(yīng)用呢?
android中有很多系統(tǒng)級(jí)別的全局變量,如時(shí)間,輸入法,賬戶,狀態(tài)欄等等
InputMethodManager類,CalendarDatabaseHelper類、Editable類等等。在這些類中,都存在一個(gè)方法getInstance,在該方法或直接返回對(duì)象的引用或判斷一個(gè)類的引用是否為NULL,若不為NULL,則直接返回該引用,若為NULL,則new一個(gè)新的對(duì)象,并返回。例如,對(duì)于CalendarDatabaseHelper類,存在如下的代碼:
public static synchronized CalendarDatabaseHelper getInstance(Contextcontext) { if (sSingleton == null) { sSingleton = newCalendarDatabaseHelper(context); } return sSingleton; }
下一篇文章將更新關(guān)于裝飾器設(shè)計(jì)模式相關(guān)的
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/92334.html
摘要:我們今天也來做一個(gè)萬能遙控器設(shè)計(jì)模式適配器模式將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。今天要介紹的仍然是創(chuàng)建型設(shè)計(jì)模式的一種建造者模式。設(shè)計(jì)模式的理論知識(shí)固然重要,但 計(jì)算機(jī)程序的思維邏輯 (54) - 剖析 Collections - 設(shè)計(jì)模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對(duì)容器接口對(duì)象進(jìn)行操作,第二類是返回一個(gè)容器接口對(duì)象,上節(jié)我們介紹了...
摘要:我們今天也來做一個(gè)萬能遙控器設(shè)計(jì)模式適配器模式將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。今天要介紹的仍然是創(chuàng)建型設(shè)計(jì)模式的一種建造者模式。設(shè)計(jì)模式的理論知識(shí)固然重要,但 計(jì)算機(jī)程序的思維邏輯 (54) - 剖析 Collections - 設(shè)計(jì)模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對(duì)容器接口對(duì)象進(jìn)行操作,第二類是返回一個(gè)容器接口對(duì)象,上節(jié)我們介紹了...
摘要:停更許久,近期計(jì)劃更新設(shè)計(jì)模式系列。單例模式是創(chuàng)建型設(shè)計(jì)模式的一種。雖然它不是正規(guī)的單例模式,但不可否認(rèn)確實(shí)具備類單例模式的特點(diǎn)。適用場(chǎng)景單例模式的特點(diǎn),意圖解決維護(hù)一個(gè)全局實(shí)例對(duì)象。 停更許久,近期計(jì)劃更新:設(shè)計(jì)模式系列。 showImg(https://segmentfault.com/img/bVbt7uw?w=800&h=600); 單例模式:限制類實(shí)例化次數(shù)只能一次,一個(gè)類只...
摘要:簡(jiǎn)介單例模式是指整個(gè)應(yīng)用中類只有一個(gè)對(duì)象實(shí)例的設(shè)計(jì)模式。它是一種常見的設(shè)計(jì)模式,在計(jì)算機(jī)系統(tǒng)中,線程池緩存日志對(duì)象對(duì)話框打印機(jī)數(shù)據(jù)庫(kù)操作顯卡的驅(qū)動(dòng)程序常被設(shè)計(jì)成單例。 簡(jiǎn)介 單例模式是指整個(gè)應(yīng)用中類只有一個(gè)對(duì)象實(shí)例的設(shè)計(jì)模式。它通常被用來創(chuàng)建對(duì)象,確保某個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。 它是一種常見的設(shè)計(jì)模式,在計(jì)算機(jī)系統(tǒng)中,線程池、緩存、日志對(duì)象、對(duì)話框、打...
閱讀 657·2021-10-27 14:15
閱讀 1185·2021-10-15 09:42
閱讀 2748·2019-08-30 15:53
閱讀 1290·2019-08-23 17:02
閱讀 2966·2019-08-23 16:23
閱讀 3183·2019-08-23 15:57
閱讀 3465·2019-08-23 14:39
閱讀 518·2019-08-23 14:35