單例模式的初步學(xué)習(xí)

做這么久的項(xiàng)目,卻沒有總結(jié)的習(xí)慣消别。再這樣下去,注定成不了好的程序員

什么是單例 :

Ensure a class only has one instance,and provide a global point of access to凌净。它的主要特點(diǎn)不是根據(jù)客戶程序調(diào)用生成一個(gè)新的實(shí)例,而是控制某個(gè)類型的實(shí)例數(shù)量-唯一一個(gè)屋讶。(《設(shè)計(jì)模式-基于C#的工程化實(shí)現(xiàn)及擴(kuò)展》冰寻,王翔)。也就是說皿渗,單例模式就是保證在整個(gè)應(yīng)用程序的生命周期中斩芭,在任何時(shí)刻,被指定的類只有一個(gè)實(shí)例乐疆,并為客戶程序提供一個(gè)獲取該實(shí)例的全局訪問點(diǎn)划乖。
特點(diǎn):
1,一個(gè)類只能有一個(gè)實(shí)例诀拭;
2迁筛,自己創(chuàng)建這個(gè)實(shí)例;
3,整個(gè)系統(tǒng)都要使用這個(gè)實(shí)例细卧。

蘋果官方單例代碼:具體點(diǎn)擊鏈接

#import
'''
/* Singleton.h */
#import <Foundation/Foundation.h>
@interfaceSingleton:NSObject
+(Singleton*)instance;
@end
/* Singleton.m */
#import "Singleton.h"
staticSingleton*instance=nil;
@implementationSingleton
+(Singleton*)instance
{
    if(!instance)
{
instance=[[superallocWithZone:NULL]init];
}
  returnin stance;
}
+(id)allocWithZone:(NSZone*)zone
{
  return [self instance];
}
-(id)copyWithZone:(NSZone*)zone
{
return self;
}
-(id)init{
if(instance)
{
return instance;
}
  self=[super init];
  return self;
}
-(id)retain{
  return self;
}
-(oneway void)release
{
  // Do nothing
}
-(id)autorelease{
return self;
}
-(NSUInteger)retainCount
{
return  NSUIntegerMax;
}
@end

參考來源

為什么用單例:

單例的意圖是為了保證一個(gè)類只有一個(gè)實(shí)例尉桩,并提供訪問它的唯一全局訪問點(diǎn)。之前一直在想贪庙,如果要完成這樣的功能蜘犁,其實(shí)全局變量也可以做到,不是嗎止邮?只要一個(gè)全局變量这橙,然后在各個(gè)需要的地方調(diào)用這個(gè)全局變量即可,必要的時(shí)候可以extern导披,一樣也可以完成這樣的功能屈扎。那么,為什么不直接使用全局變量撩匕,而要搞一個(gè)單例出來鹰晨?單例到底比全局變量好在哪兒?首先止毕,全局變量不能保證全局只有一個(gè)類的實(shí)例模蜡,你完全可以聲明同一個(gè)類的多個(gè)實(shí)例。當(dāng)然扁凛,如果你注意一點(diǎn)忍疾,那么用全局方法保證全局只有一個(gè)該類的實(shí)例還是可以做到的,但你得很注意谨朝,讓自己不要在其他地方聲明多一個(gè)實(shí)例卤妒。而單例卻可以輕松的做到這一點(diǎn),并能保證全局只有一個(gè)該類的實(shí)例可被訪問叠必。其次荚孵,相對(duì)來說,使用單例時(shí)纬朝,代碼會(huì)顯得優(yōu)雅一些收叶。
單例模式與全局變量的詳細(xì)比較
單例模式的其他應(yīng)用場(chǎng)景

什么時(shí)候用單例

單例的使用主要是在需要保證全局只有一個(gè)實(shí)例可以被訪問的情況,比如[系統(tǒng)]日志的輸出共苛、[操作系統(tǒng)]的任務(wù)管理器等判没。
一些細(xì)節(jié)
通常,我們看到的單例類沒有析構(gòu)函數(shù)隅茎,那么new出來的[空間]是怎么釋放的呢澄峰?一般有2種做法,一種是不做任何操作辟犀,等最后程序結(jié)束時(shí)操作系統(tǒng)回收[資源]俏竞;另外一種是另外搞一個(gè)函數(shù)或者類,來處理delete操作。對(duì)于像我這樣的初級(jí)使用學(xué)者魂毁,還是選擇第一種更方便玻佩,第二種相對(duì)來說需要考慮更多一些。

兩種經(jīng)典的多線程單例寫法

 一席楚、經(jīng)典模式:
publicclass Singleton
{
privatestatic Singleton instance;
private Singleton()
{}
publicstatic Singleton GetInstance()
{
  if(instance==null)
{
  instance=new Singleton();
}
  return instance;
}


  解析如下:
  1)首先咬崔,該Singleton的構(gòu)造函數(shù)必須是私有的,以保證客戶程序不會(huì)通過new()操作產(chǎn)生一個(gè)實(shí)例烦秩,達(dá)到實(shí)現(xiàn)單例的目的垮斯;
  2)因?yàn)殪o態(tài)變量的生命周期跟整個(gè)應(yīng)用程序的生命周期是一樣的,所以可以定義一個(gè)私有的靜態(tài)全局變量instance來保存該類的唯一實(shí)例只祠;
  3)必須提供一個(gè)全局函數(shù)訪問獲得該實(shí)例兜蠕,并且在該函數(shù)提供控制實(shí)例數(shù)量的功能,即通過if語句判斷instance是否已被實(shí)例化抛寝,如果沒有則可以同new()創(chuàng)建一個(gè)實(shí)例牺氨;否則,直接向客戶返回一個(gè)實(shí)例墩剖。
  在這種經(jīng)典模式下,沒有考慮線程并發(fā)獲取實(shí)例問題夷狰,即可能出現(xiàn)兩個(gè)線程同時(shí)獲取instance實(shí)例岭皂,且此時(shí)其為null時(shí),就會(huì)出現(xiàn)兩個(gè)線程分別創(chuàng)建了instance沼头,違反了單例規(guī)則爷绘。因此,需對(duì)上面代碼修改进倍。
  二土至、多線程下的單例模式
  1、Lazy模式

publicclass Singleton
{
privatestatic Singleton instance;

private Singleton()
{

}

publicstatic Singleton GetInstance()
{
if(instance==null)
{
instance=new Singleton();
}
return instance;
}
}
  上述代碼使用了雙重鎖方式較好地解決了多線程下的單例模式實(shí)現(xiàn)猾昆。先看內(nèi)層的if語句塊陶因,使用這個(gè)語句塊時(shí),先進(jìn)行加鎖操作垂蜗,保證只有一個(gè)線程可以訪問該語句塊楷扬,進(jìn)而保證只創(chuàng)建了一個(gè)實(shí)例。再看外層的if語句塊贴见,這使得每個(gè)線程欲獲取實(shí)例時(shí)不必每次都得加鎖烘苹,因?yàn)橹挥袑?shí)例為空時(shí)(即需要?jiǎng)?chuàng)建一個(gè)實(shí)例),才需加鎖創(chuàng)建片部,若果已存在一個(gè)實(shí)例镣衡,就直接返回該實(shí)例,節(jié)省了性能開銷。
  2廊鸥、餓漢模式
  這種模式的特點(diǎn)是自己主動(dòng)實(shí)例望浩。
publicclass Singleton
{
privatestatic Singleton instance;
privatestaticobject _lock=newobject();

private Singleton()
{

}

publicstatic Singleton GetInstance()
{
if(instance==null)
{
lock(_lock)
{
if(instance==null)
{
instance=new Singleton();
}
}
}
return instance;
}
}

  上面使用的readonly關(guān)鍵可以跟static一起使用,用于指定該常量是類別級(jí)的黍图,它的初始化交由靜態(tài)構(gòu)造函數(shù)實(shí)現(xiàn)曾雕,并可以在運(yùn)行時(shí)編譯。在這種模式下助被,無需自己解決線程安全性問題剖张,CLR會(huì)給我們解決。由此可以看到這個(gè)類被加載時(shí)揩环,會(huì)自動(dòng)實(shí)例化這個(gè)類搔弄,而不用在第一次調(diào)用GetInstance()后才實(shí)例化出唯一的單例對(duì)象。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末丰滑,一起剝皮案震驚了整個(gè)濱河市顾犹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌褒墨,老刑警劉巖炫刷,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異郁妈,居然都是意外死亡浑玛,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門噩咪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來顾彰,“玉大人,你說我怎么就攤上這事胃碾≌窍恚” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵仆百,是天一觀的道長厕隧。 經(jīng)常有香客問我,道長俄周,這世上最難降的妖魔是什么栏账? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮栈源,結(jié)果婚禮上挡爵,老公的妹妹穿的比我還像新娘。我一直安慰自己甚垦,他們只是感情好茶鹃,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布涣雕。 她就那樣靜靜地躺著,像睡著了一般闭翩。 火紅的嫁衣襯著肌膚如雪挣郭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天疗韵,我揣著相機(jī)與錄音兑障,去河邊找鬼。 笑死蕉汪,一個(gè)胖子當(dāng)著我的面吹牛流译,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播者疤,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼福澡,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了驹马?” 一聲冷哼從身側(cè)響起革砸,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎糯累,沒想到半個(gè)月后算利,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡泳姐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年笔时,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仗岸。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖借笙,靈堂內(nèi)的尸體忽然破棺而出扒怖,到底是詐尸還是另有隱情,我是刑警寧澤业稼,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布盗痒,位于F島的核電站,受9級(jí)特大地震影響低散,放射性物質(zhì)發(fā)生泄漏俯邓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一熔号、第九天 我趴在偏房一處隱蔽的房頂上張望稽鞭。 院中可真熱鬧,春花似錦引镊、人聲如沸朦蕴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吩抓。三九已至涉茧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間疹娶,已是汗流浹背伴栓。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留雨饺,地道東北人钳垮。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像沛膳,于是被迫代替她去往敵國和親扔枫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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

  • 單例模式(SingletonPattern)一般被認(rèn)為是最簡單锹安、最易理解的設(shè)計(jì)模式短荐,也因?yàn)樗暮啙嵰锥琼?xiàng)目中最...
    成熱了閱讀 4,231評(píng)論 4 34
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理叹哭,服務(wù)發(fā)現(xiàn)忍宋,斷路器,智...
    卡卡羅2017閱讀 134,629評(píng)論 18 139
  • 1 場(chǎng)景問題# 1.1 讀取配置文件的內(nèi)容## 考慮這樣一個(gè)應(yīng)用风罩,讀取配置文件的內(nèi)容糠排。 很多應(yīng)用項(xiàng)目,都有與應(yīng)用相...
    七寸知架構(gòu)閱讀 6,675評(píng)論 12 68
  • 前言 本文主要參考 那些年超升,我們一起寫過的“單例模式”入宦。 何為單例模式? 顧名思義室琢,單例模式就是保證一個(gè)類僅有一個(gè)...
    tandeneck閱讀 2,488評(píng)論 1 8
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法乾闰,類相關(guān)的語法,內(nèi)部類的語法盈滴,繼承相關(guān)的語法涯肩,異常的語法,線程的語...
    子非魚_t_閱讀 31,598評(píng)論 18 399