單例模式 (Singleton)

本文主要根據(jù)以下著作中的內(nèi)容整理而來:

何紅輝,關(guān)愛民.Android源碼設(shè)計模式解析與實踐第2版〔M〕.北京:人民郵電出版社棱诱,2017.7

定義

確保某一個類只有一個實例疗绣,自行實例化并向整個系統(tǒng)提供這個實例烙懦。

角色

Client——高層客戶端踪区。

Singleton——單例類。

特點

私有:構(gòu)造方法是私有的吊骤,靜態(tài)變量是私有的缎岗。

靜態(tài):通過一個公有的靜態(tài)方法或枚舉返回單例類對象。

線程安全:多線程環(huán)境下也要確保對象只有一個白粉。

幾種實現(xiàn)方式

以下幾種方式在初始化靜態(tài)對象上有不同传泊。

餓漢模式:聲明靜態(tài)對象時直接初始化鼠渺。new的過程很耗時的話,應(yīng)用程序啟動的會很慢眷细,降低體驗的友好性

懶漢模式:聲明一個靜態(tài)對象拦盹,在用戶第一次調(diào)用getInstance()時初始化。延遲單例的實例化溪椎。

? ? ? ? ? ? ? ??懶漢模式 問題:getInstance的調(diào)用頻率很高的話普舆,每次都synchronized同步訪問,效率低校读。

雙重檢查鎖定(DCL):既能在需要時初始化沼侣,又能保證線程安全,消除懶漢模式中重復(fù)同步問題歉秫。(得比較多的方式蛾洛,JDK1.5及以上版本使用volatile,沒有復(fù)雜的并發(fā)場景下一般能滿足使用)

靜態(tài)內(nèi)部類:解決雙重檢查鎖定失效問題雁芙。(推薦使用的實現(xiàn)方式)

代碼示例

雙重檢查鎖定方式:

public class Singleton{

? ? //問題1:new操作的反匯編代碼轧膘,其實他包含3條匯編指令:new、dup兔甘、init谎碍。sInstance 不為null并不保證sInstance是完整地初始化好了成員。

? ? // 問題2:即使一個線程實例化了sInstance 裂明,由于每個線程都有自己的working緩存椿浓,可能另一個線程看不到前一個線程對sInstance 的操作。

? ? // JDK1.5及以后 使用volatile關(guān)鍵字闽晦,保證每次sInstance都是從主內(nèi)存中獲取扳碍。

? ? private volatile static Single sInstance = null;

? ? private Singleton(){}

? ? public static Singleton getInstance(){

? ? ? ? if(sInstance==null){

? ? ? ? ? ? synchronize(Singleton.class){

? ? ? ? ? ? ? ? if(sInstance==null){

? ? ? ? ? ? ? ? ? ? ?? sInstance = new Singleton();//實際上不是一個原子操作:1.給Singleton實例分配內(nèi)存;2.調(diào)用Singleton()構(gòu)造方法初始化成員字段仙蛉;3.將sInstance指向分配的內(nèi)存空間笋敞。 執(zhí)行順序可能是1-2-3或者1-2-3。

????????????????}

????????????}

????????}

????}

}

靜態(tài)內(nèi)部類方式:

public class Singleton{

? ? private?Singleton(){}

????public static?Singleton getInstance(){

? ? ? ? // 延遲初始化

? ? ? ? return SingletonHolder.sInstance;

????}

?? private static class SingletonHolder{

? ? ? ? //靜態(tài)變量是線程共享的荠瘪,保證了單例的線程安全躏救。避免了雙重檢查鎖定失效問題吱瘩。

? ? ? ? private static final Singleton sInstance = new?Singleton();

????}

}

擴展應(yīng)用

使用容器實現(xiàn)單例

Android Context的實現(xiàn)類ContextImpl

public class ContextImpl extends Context {

? ? private final static Map<String,ServiceFetcher> SYSTEM_SERVICE_MAP= new HashMap<String,ServiceFetcher>();

? ? public static void registerService(String serviceName,ServiceFetcher fetcher){

? ? ? ? //省略代碼

????????SYSTEM_SERVICE_MAP.put(serviceName,fetcher);

????}

? ? public Object getSystemService(String key){

? ? ? ? ServiceFetcher fetcher =?SYSTEM_SERVICE_MAP.get(key);

? ? ? ? return fetcher ==null? null:fetcher.getService(this)

????}

? ? static {

? ? ? ? registerService(LAYOUT_INFLATER_SERVICE,new ServiceFetcher(){

? ? ? ? ? ? public Object createService(ContextImpl ctx){

? ? ? ? ? ? ? ? return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());

????????????}

????????})

????}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子挽放,更是在濱河造成了極大的恐慌,老刑警劉巖喘蟆,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件镇眷,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機臀突,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進店門勉抓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人候学,你說我怎么就攤上這事藕筋。” “怎么了梳码?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵隐圾,是天一觀的道長。 經(jīng)常有香客問我边翁,道長翎承,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任符匾,我火速辦了婚禮叨咖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘啊胶。我一直安慰自己甸各,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布焰坪。 她就那樣靜靜地躺著趣倾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪某饰。 梳的紋絲不亂的頭發(fā)上儒恋,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天,我揣著相機與錄音黔漂,去河邊找鬼诫尽。 笑死,一個胖子當(dāng)著我的面吹牛炬守,可吹牛的內(nèi)容都是我干的牧嫉。 我是一名探鬼主播,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼减途,長吁一口氣:“原來是場噩夢啊……” “哼酣藻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鳍置,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤辽剧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后税产,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怕轿,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡坊夫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了撤卢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡梧兼,死狀恐怖放吩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情羽杰,我是刑警寧澤渡紫,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站考赛,受9級特大地震影響惕澎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜颜骤,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一唧喉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧忍抽,春花似錦八孝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至祟绊,卻和暖如春楼入,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背牧抽。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工嘉熊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人阎姥。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓记舆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親呼巴。 傳聞我的和親對象是個殘疾皇子泽腮,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,876評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 暑假诊赊,看了《微微一笑很傾城》之后,受了很大的鼓舞府瞄。發(fā)現(xiàn)大學(xué)期間碧磅,自己應(yīng)該找一個適合自己的游戲狠狠的玩一把碘箍。 于是,...
    63b7d873d779閱讀 585評論 0 1
  • 這一晚 我開始認真思考自己要不要考研了。 回來家中幾日 隨著就業(yè)形勢的嚴(yán)峻以及我本身對于自身能力評估較低 我想 我...
    灰鴿不灰閱讀 234評論 0 0
  • 目錄:不長不短,剛好刻骨銘心 上一章:風(fēng)波 文/陳康慧 辰宇眼睛紅紅的從沙發(fā)上站起身來职辨,拉著還在哭泣的夕瑤就往外面...
    陳康慧閱讀 742評論 2 16