Android 單例模式的四種實(shí)現(xiàn)方式
一.餓漢式
public class SingletionStarving { private static final SingletionStarving mInstance = new SingletionStarving(); private SingletionStarving() { } public static SingletionStarving getInstance() { return mInstance; } }
- 構(gòu)造函數(shù)用private修飾,外部無法訪問
- 聲明靜態(tài)對(duì)象時(shí)就初始化
- static關(guān)鍵字修飾,靜態(tài)變量,存儲(chǔ)在內(nèi)存中,只有一份數(shù)據(jù)。
- final關(guān)鍵字,只初始化一次,所以mInstance實(shí)例只有一個(gè)。
二.懶漢式
public class SingletionSlacker { private static SingletionSlacker mInstance; private SingletionSlacker() {} public static synchronized SingletionSlacker getInstance() { if (mInstance == null) { mInstance = new SingletionSlacker(); } return mInstance; } }
- 構(gòu)造函數(shù)用private修飾,外部無法訪問
- 使用的時(shí)候即調(diào)用getInstance的時(shí)候才初始化
- static關(guān)鍵字修飾,靜態(tài)變量,存儲(chǔ)在內(nèi)存中,只有一份數(shù)據(jù)。
- synchronized線程安全,多線程情況下單例的唯一性
- 缺點(diǎn):沒次調(diào)用getInstance都會(huì)同步一次,浪費(fèi)資源
三.雙重檢查加鎖方式
網(wǎng)上建議和使用最多的方法
public class Singletion { private static Singletion mInstance; private Singletion() {} public static Singletion getmInstance() { if (mInstance == null) { synchronized (Singletion.class) { if (mInstance == null) { mInstance = new Singletion (); } } } return mInstance; } }
- 構(gòu)造函數(shù)用private修飾,外部無法訪問
- 使用的時(shí)候即調(diào)用getInstance的時(shí)候才初始化
- static關(guān)鍵字修飾,靜態(tài)變量,存儲(chǔ)在內(nèi)存中,只有一份數(shù)據(jù)
- synchronized線程安全,多線程情況下單例的唯一性
- 兩次判斷空,避免多次同步(synchronized)
缺點(diǎn)
private static Singletion mInstance; private Singletion() {} public static Singletion getmInstance() {}
由于jvm特性,允許亂序執(zhí)行,上面三句代碼順序不定,那么就可能出現(xiàn)失效的問題。
步驟一、倘若A線程執(zhí)行g(shù)etmInstance(),還沒執(zhí)行構(gòu)造方法Singletion()
步驟二、此時(shí)B線程調(diào)用getmInstance()。因?yàn)锳已經(jīng)執(zhí)行g(shù)etmInstance(),所以mInstance不為空就直接獲取。
步驟三、由于B直接獲取,而真實(shí)情況是A線程構(gòu)造方法還未執(zhí)行,所以mInstance就為空了。
雖然此情況發(fā)生概率較小,但也是一種情況。為了解決這種情況,java1.6開始加入volatile關(guān)鍵字
private volatile static Singletion mInstance;
這樣就避免了方式失效的情況。雖然會(huì)volatile消耗一些性能,所以最佳寫法
public class Singletion { private volatile static Singletion mInstance; private Singletion () {} public static Singletion getmInstance() { if (mInstance == null) { synchronized (Singletion.class) { if (mInstance == null) { mInstance = new Singletion(); } } } return mInstance; } }
雖然volatile讓方式完美,但是沒有volatile關(guān)鍵字的寫法基本能滿足絕大部分情況。除非你要運(yùn)行在高并發(fā),或者java1.6之前的代碼中。
四.靜態(tài)內(nèi)部類方式
public class SingletionInternalClass { private SingletionInternalClass() {} public static SingletionInternalClass getInstance() { return SingletionInternalClassHolder.instance; } private static class SingletionInternalClassHolder { private static final SingletionInternalClass instance = new SingletionInternalClass(); } }
構(gòu)造函數(shù)用private修飾,外部無法訪問
使用的時(shí)候即調(diào)用getInstance的時(shí)候才初始化
調(diào)用getInstance才回去加載SingletionInternalClassHolder類,確保了線程安全,保證了單例的唯一性
總結(jié)
單例模式不管用那種方式實(shí)現(xiàn),核心思想都相同
1、構(gòu)造函數(shù)私有化,通過一次靜態(tài)方法獲取一個(gè)唯一實(shí)例
2、線程安全
最后推薦使用文中**雙重鎖方式和靜態(tài)內(nèi)部類的方式**來創(chuàng)建單例模式。
以上就是Android 單例模式的四種實(shí)現(xiàn)方式的詳細(xì)內(nèi)容,更多關(guān)于Android 單例模式的實(shí)現(xiàn)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- 如何在Android studio 中使用單例模式
- Android中單例模式的一些坑小結(jié)
- Android開發(fā)中的單例模式應(yīng)用詳解
- Android編程設(shè)計(jì)模式之單例模式實(shí)例詳解
- Android設(shè)計(jì)模式之單例模式解析
- Android設(shè)計(jì)模式之單例模式詳解
- Android單例模式的幾種方法總結(jié)
- Android 單例模式 Singleton 簡單實(shí)例設(shè)計(jì)模式解析
- android開發(fā)設(shè)計(jì)模式之——單例模式詳解
- Android設(shè)計(jì)模式系列之單例模式
- android設(shè)計(jì)模式之單例模式詳解
- Android源碼學(xué)習(xí)之單例模式應(yīng)用及優(yōu)點(diǎn)介紹
相關(guān)文章
在Ubuntu下搭建Android開發(fā)環(huán)境
對(duì)一個(gè)程序猿來說,裝好系統(tǒng)之后的第一件事,一定是搭建開發(fā)環(huán)境,已經(jīng)安裝各種開發(fā)工具,以便之后能方便順利地進(jìn)行程序的開發(fā)。簡單的介紹下在Ubuntu環(huán)境下搭建Android開發(fā)環(huán)境,雖然基本上和在Windows下沒有太大差別,但有些細(xì)節(jié)上還是很值得注意的。2014-07-07Android開發(fā)實(shí)現(xiàn)ImageView加載攝像頭拍攝的大圖功能
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)ImageView加載攝像頭拍攝的大圖功能,涉及Android基于ImageView的攝像頭拍攝圖片加載、保存及權(quán)限控制等相關(guān)操作技巧,需要的朋友可以參考下2017-11-11OpenGL ES正交投影實(shí)現(xiàn)方法(三)
這篇文章主要為大家詳細(xì)介紹了OpenGL ES正交投影的實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05Android ListView下拉刷新上拉自動(dòng)加載更多DEMO示例
這篇文章主要介紹了Android ListView下拉刷新上拉自動(dòng)加載更多DEMO示例的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-07-07Android 通過當(dāng)前經(jīng)緯度獲得城市的實(shí)例代碼
Android 通過當(dāng)前經(jīng)緯度獲得城市的實(shí)例代碼,需要的朋友可以參考一下2013-06-06Android 自定義View結(jié)合自定義TabLayout實(shí)現(xiàn)頂部標(biāo)簽滑動(dòng)效果
小編最近在做app的項(xiàng)目,需要用到tablayout實(shí)現(xiàn)頂部的滑動(dòng)效果,文中代碼用到了自定義item,代碼也很簡單,感興趣的朋友跟隨腳本之家小編一起看看吧2018-07-07Android開發(fā)中TextView文本過長滾動(dòng)顯示實(shí)現(xiàn)方法分析
這篇文章主要介紹了Android開發(fā)中TextView文本過長滾動(dòng)顯示實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了Android項(xiàng)目開發(fā)中TextView顯示超長文本的具體操作技巧與注意事項(xiàng),需要的朋友可以參考下2018-02-02