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