android開發(fā)設(shè)計(jì)模式之——單例模式詳解
單例模式是設(shè)計(jì)模式中最常見(jiàn)也最簡(jiǎn)單的一種設(shè)計(jì)模式,保證了在程序中只有一個(gè)實(shí)例存在并且能全局的訪問(wèn)到。比如在Android實(shí)際APP 開發(fā)中用到的 賬號(hào)信息對(duì)象管理, 數(shù)據(jù)庫(kù)對(duì)象(SQLiteOpenHelper)等都會(huì)用到單例模式。下面針對(duì)一些例子分析一下我們?cè)陂_發(fā)過(guò)程中應(yīng)用單例模式需要注意的點(diǎn)。
一、作用
單例模式(Singleton):保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問(wèn)它的全局訪問(wèn)點(diǎn)
二、適用場(chǎng)景
1. 應(yīng)用中某個(gè)實(shí)例對(duì)象需要頻繁的被訪問(wèn)。
2. 應(yīng)用中每次啟動(dòng)只會(huì)存在一個(gè)實(shí)例。如賬號(hào)系統(tǒng),數(shù)據(jù)庫(kù)系統(tǒng)。
三、常用的使用方式
(1)懶漢式
這是在開發(fā)中很容易就能寫出來(lái)的一種方式,如下
public class Singleton {
/* 持有私有靜態(tài)實(shí)例,防止被引用,此處賦值為null,目的是實(shí)現(xiàn)延遲加載 */
private static Singleton instance = null;
/* 私有構(gòu)造方法,防止被實(shí)例化 */
private Singleton() {
}
/* 1:懶漢式,靜態(tài)工程方法,創(chuàng)建實(shí)例 */
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
調(diào)用:
Singleton.getInstance().method();
優(yōu)點(diǎn):延遲加載(需要的時(shí)候才去加載)
缺點(diǎn): 線程不安全,在多線程中很容易出現(xiàn)不同步的情況,如在數(shù)據(jù)庫(kù)對(duì)象進(jìn)行的頻繁讀寫操作時(shí)。
(2)加同步鎖
既然線程不安全,那就加上同步鎖,一種加法如下:
/*2.懶漢式變種,解決線程安全問(wèn)題**/
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
更一般的寫法是這樣
/*加上synchronized,但是每次調(diào)用實(shí)例時(shí)都會(huì)加載**/
public static Singleton getInstance() {
synchronized (Singletonclass) {
if (instance == null) {
instance = new Singleton();
}
}
return instance;
}
調(diào)用:
Singleton.getInstance().method();
優(yōu)點(diǎn):解決了線程不安全的問(wèn)題。
缺點(diǎn):效率有點(diǎn)低,每次調(diào)用實(shí)例都要判斷同步鎖
補(bǔ)充:在Android源碼中使用的該單例方法有:InputMethodManager,AccessibilityManager等都是使用這種單例模式
(3)雙重檢驗(yàn)鎖
要優(yōu)化(2)中因?yàn)槊看握{(diào)用實(shí)例都要判斷同步鎖的問(wèn)題,很多人都使用下面的一種雙重判斷校驗(yàn)的辦法
/*3.雙重鎖定:只在第一次初始化的時(shí)候加上同步鎖*/
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singletonclass) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
這種方法貌似很完美的解決了上述效率的問(wèn)題,它或許在并發(fā)量不多,安全性不太高的情況能完美運(yùn)行,但是,這種方法也有不幸的地方。問(wèn)題就是出現(xiàn)在這句
instance = new Singleton();
在JVM編譯的過(guò)程中會(huì)出現(xiàn)指令重排的優(yōu)化過(guò)程,這就會(huì)導(dǎo)致當(dāng) instance實(shí)際上還沒(méi)初始化,就可能被分配了內(nèi)存空間,也就是說(shuō)會(huì)出現(xiàn) instance !=null 但是又沒(méi)初始化的情況,這樣就會(huì)導(dǎo)致返回的 instance 不完整
調(diào)用:
Singleton.getInstance().method();
優(yōu)點(diǎn):在并發(fā)量不多,安全性不高的情況下或許能很完美運(yùn)行單例模式
缺點(diǎn):不同平臺(tái)編譯過(guò)程中可能會(huì)存在嚴(yán)重安全隱患。
補(bǔ)充:在android圖像開源項(xiàng)目Android-Universal-Image-Loader中使用的是這種方式。
(4)內(nèi)部類的實(shí)現(xiàn)
內(nèi)部類是一種好的實(shí)現(xiàn)方式,可以推薦使用一下:
public class SingletonInner {
/**
* 內(nèi)部類實(shí)現(xiàn)單例模式
* 延遲加載,減少內(nèi)存開銷
*
* @author xuzhaohu
*
*/
private static class SingletonHolder {
private static SingletonInner instance = new SingletonInner();
}
/**
* 私有的構(gòu)造函數(shù)
*/
private SingletonInner() {
}
public static SingletonInner getInstance() {
return SingletonHolderinstance;
}
protected void method() {
Systemoutprintln("SingletonInner");
}
}
調(diào)用:
SingletonInner.getInstance().method();
優(yōu)點(diǎn):延遲加載,線程安全(java中class加載時(shí)互斥的),也減少了內(nèi)存消耗
(5)枚舉的方法
這是網(wǎng)上很多人推薦的一種做法,但是貌似使用的不廣泛,大家可以試試,
/**
* @function:單例模式枚舉實(shí)現(xiàn)
* @author xuzhaohu
*
*/
public enum SingletonEnum {
/**
* 從Java5開始支持;
* 無(wú)償提供序列化機(jī)制;
* 絕對(duì)防止多次實(shí)例化,即使在面對(duì)復(fù)雜的序列化或者反射攻擊的時(shí)候;
*/
instance;
private String others;
SingletonEnum() {
}
public void method() {
Systemoutprintln("SingletonEnum");
}
public String getOthers() {
return others;
}
public void setOthers(String others) {
thisothers = others;
}
}
調(diào)用:
SingletonEnum.instance.method();
優(yōu)缺點(diǎn):如代碼中注釋。
上面主要講了單例模式5種創(chuàng)建方法,大家可以根據(jù)其優(yōu)缺點(diǎn)進(jìn)行個(gè)人實(shí)際項(xiàng)目中的使用。講的屬于拋磚引玉,大家多提意見(jiàn)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android this與Activity.this的區(qū)別
這篇文章主要介紹了 Android this與Activity.this的區(qū)別的相關(guān)資料,需要的朋友可以參考下2016-09-09
Android常用三方庫(kù)混淆規(guī)則整理(小結(jié))
這篇文章主要介紹了Android常用三方庫(kù)混淆規(guī)則整理(小結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
Android android:exported = true 用法詳解
在本篇文章里小編給大家整理了關(guān)于Android android:exported = true 用法,需要的朋友們參考下。2019-09-09
Android開發(fā):淺談MVP模式應(yīng)用與內(nèi)存泄漏問(wèn)題解決
本篇文章主要介紹了Android開發(fā):MVP模式應(yīng)用與內(nèi)存泄漏問(wèn)題解決,具有一定的參考價(jià)值,有需要的可以了解一下。2016-11-11
Android實(shí)現(xiàn)一個(gè)比相冊(cè)更高大上的左右滑動(dòng)特效(附源碼)
這篇文章主要介紹了Android實(shí)現(xiàn)一個(gè)比相冊(cè)更高大上的左右滑動(dòng)特效(附源碼),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
Android實(shí)用控件自定義逼真相機(jī)光圈View
這篇文章主要為大家詳細(xì)介紹了Android實(shí)用控件自定義逼真相機(jī)光圈,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08

