Android開發設計模式之——單例模式

http://blog.csdn.net/beyond0525/article/details/22794221

單例模式是設計模式中最常見也最簡單的一種設計模式,保證了在程序中只有一個實例存在并且能全局的訪問到。比如在Android實際APP 開發中用到的 賬號信息對象管理,數據庫對象(SQLiteOpenHelper)等都會用到單例模式。下面針對一些例子分析一下我們在開發過程中應用單例模式需要注意的點。

一、作用

單例模式(Singleton):保證一個類僅有一個實例,并提供一個訪問它的全局訪問點

二、適用場景

1. 應用中某個實例對象需要頻繁的被訪問。

2. 應用中每次啟動只會存在一個實例。如賬號系統,數據庫系統。

三、常用的使用方式

(1)懶漢式

這是在開發中很容易就能寫出來的一種方式,如下

[java]view plaincopy

publicclassSingleton?{

/*?持有私有靜態實例,防止被引用,此處賦值為null,目的是實現延遲加載?*/

privatestaticSingleton?instance?=null;

/*?私有構造方法,防止被實例化?*/

privateSingleton()?{

}

/*?1:懶漢式,靜態工程方法,創建實例?*/

publicstaticSingleton?getInstance()?{

if(instance?==null)?{

instance?=newSingleton();

}

returninstance;

}

}

調用:

[java]view plaincopy

Singleton.getInstance().method();

優點:延遲加載(需要的時候才去加載)

缺點: 線程不安全,在多線程中很容易出現不同步的情況,如在數據庫對象進行的頻繁讀寫操作時。

(2)加同步鎖

既然線程不安全,那就加上同步鎖,一種加法如下:

[java]view plaincopy

/*2.懶漢式變種,解決線程安全問題**/

publicstaticsynchronizedSingleton?getInstance()?{

if(instance?==null)?{

instance?=newSingleton();

}

returninstance;

}

更一般的寫法是這樣

[java]view plaincopy

/*加上synchronized,但是每次調用實例時都會加載**/

publicstaticSingleton?getInstance()?{

synchronized(Singleton.class)?{

if(instance?==null)?{

instance?=newSingleton();

}

}

returninstance;

}

調用:

[java]view plaincopy

Singleton.getInstance().method();

優點:解決了線程不安全的問題。

缺點:效率有點低,每次調用實例都要判斷同步鎖

補充:android源碼中使用的該單例方法有:InputMethodManager,AccessibilityManager等都是使用這種單例模式

(3)雙重檢驗鎖

要優化(2)中因為每次調用實例都要判斷同步鎖的問題,很多人都使用下面的一種雙重判斷校驗的辦法

[java]view plaincopy

/*3.雙重鎖定:只在第一次初始化的時候加上同步鎖*/

publicstaticSingleton?getInstance()?{

if(instance?==null)?{

synchronized(Singleton.class)?{

if(instance?==null)?{

instance?=newSingleton();

}

}

}

returninstance;

}

這種方法貌似很完美的解決了上述效率的問題,它或許在并發量不多,安全性不太高的情況能完美運行,但是,這種方法也有不幸的地方。問題就是出現在這句

[java]view plaincopy

instance?=newSingleton();

在JVM編譯的過程中會出現指令重排的優化過程,這就會導致當 instance實際上還沒初始化,就可能被分配了內存空間,也就是說會出現 instance !=null 但是又沒初始化的情況,這樣就會導致返回的?instance 不完整(可以參考:http://www.360doc.com/content/11/0810/12/1542811_139352888.shtml)。

調用:

[java]view plaincopy

Singleton.getInstance().method();

優點:在并發量不多,安全性不高的情況下或許能很完美運行單例模式

缺點:不同平臺編譯過程中可能會存在嚴重安全隱患。

補充:在android圖像開源項目Android-Universal-Image-Loaderhttps://github.com/nostra13/Android-Universal-Image-Loader中使用的是這種方式

(4)內部類的實現

內部類是一種好的實現方式,可以推薦使用一下:

[java]view plaincopy

publicclassSingletonInner?{

/**

*?內部類實現單例模式

*?延遲加載,減少內存開銷

*

*?@author?xuzhaohu

*

*/

privatestaticclassSingletonHolder?{

privatestaticSingletonInner?instance?=newSingletonInner();

}

/**

*?私有的構造函數

*/

privateSingletonInner()?{

}

publicstaticSingletonInner?getInstance()?{

returnSingletonHolder.instance;

}

protectedvoidmethod()?{

System.out.println("SingletonInner");

}

}

調用:

[java]view plaincopy

SingletonInner.getInstance().method();

優點:延遲加載,線程安全(java中class加載時互斥的),也減少了內存消耗

(5)枚舉的方法

這是網上很多人推薦的一種做法,但是貌似使用的不廣泛,大家可以試試,

[java]view plaincopy

/**

*?@function:單例模式枚舉實現

*?@author?xuzhaohu

*

*/

publicenumSingletonEnum?{

/**

*?1.從Java1.5開始支持;

*?2.無償提供序列化機制;

*?3.絕對防止多次實例化,即使在面對復雜的序列化或者反射攻擊的時候;

*/

instance;

privateString?others;

SingletonEnum()?{

}

publicvoidmethod()?{

System.out.println("SingletonEnum");

}

publicString?getOthers()?{

returnothers;

}

publicvoidsetOthers(String?others)?{

this.others?=?others;

}

}

調用:

[java]view plaincopy

SingletonEnum.instance.method();

優缺點:如代碼中注釋。

上面主要講了單例模式5種創建方法,大家可以根據其優缺點進行個人實際項目中的使用。講的屬于拋磚引玉,大家多提意見。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內容