單例

單例模式(Singleton Pattern):確保某一個類只有一個實例,而且自行實例化并向整個系統(tǒng)提供這個實例锥咸,這個類稱為單例類靶溜,它提供全局訪問的方法。單例模式是一種對象創(chuàng)建型模式录煤。

單例模式有三個要點:一是某個類只能有一個實例;二是它必須自行創(chuàng)建這個實例荞胡;三是它必須自行向整個系統(tǒng)提供這個實例妈踊。

單例模式是結構最簡單的設計模式一,在它的核心結構中只包含一個被稱為單例類的特殊類泪漂。

單例模式結構圖中只包含一個單例角色:

Singleton(單例):在單例類的內部實現(xiàn)只生成一個實例廊营,同時它提供一個靜態(tài)的getInstance()工廠方法,讓客戶可以訪問它的唯一實例萝勤;為了防止在外部對其實例化露筒,將其構造函數(shù)設計為私有;在單例類內部定義了一個Singleton類型的靜態(tài)對象敌卓,作為外部共享的唯一實例慎式。

主要優(yōu)點:

1、提供了對唯一實例的受控訪問趟径。

2瘪吏、由于在系統(tǒng)內存中只存在一個對象,因此可以節(jié)約系統(tǒng)資源蜗巧,對于一些需要頻繁創(chuàng)建和銷毀的對象單例模式無疑可以提高系統(tǒng)的性能掌眠。

3、允許可變數(shù)目的實例惧蛹。

主要缺點:

1扇救、由于單利模式中沒有抽象層刑枝,因此單例類的擴展有很大的困難香嗓。

2、單例類的職責過重装畅,在一定程度上違背了“單一職責原則”靠娱。

3、濫用單例將帶來一些負面問題掠兄,如為了節(jié)省資源將數(shù)據庫連接池對象設計為的單例類像云,可能會導致共享連接池對象的程序過多而出現(xiàn)連接池溢出锌雀;如果實例化的對象長時間不被利用,系統(tǒng)會認為是垃圾而被回收迅诬,這將導致對象狀態(tài)的丟失腋逆。

適用場景

在以下情況下可以考慮使用單例模式:

- (1) 系統(tǒng)只需要一個實例對象,如系統(tǒng)要求提供一個唯一的序列號生成器或資源管理器侈贷,或者需要考慮資源消耗太大而只允許創(chuàng)建一個對象惩歉。

- (2) 客戶調用類的單個實例只允許使用一個公共訪問點,除了該公共訪問點俏蛮,不能通過其他途徑訪問該實例撑蚌。

餓漢式單例類與懶漢式單例類比較

餓漢式單例類在類被加載時就將自己實例化,它的優(yōu)點在于無須考慮多線程訪問問題搏屑,可以確保實例的唯一性争涌;從調用速度和反應時間角度來講,由于單例對象一開始就得以創(chuàng)建辣恋,因此要優(yōu)于懶漢式單例亮垫。但是無論系統(tǒng)在運行時是否需要使用該單例對象,由于在類加載時該對象就需要創(chuàng)建伟骨,因此從資源利用效率角度來講包警,餓漢式單例不及懶漢式單例,而且在系統(tǒng)加載時由于需要創(chuàng)建餓漢式單例對象底靠,加載時間可能會比較長害晦。

懶漢式單例類在第一次使用時創(chuàng)建,無須一直占用系統(tǒng)資源暑中,實現(xiàn)了延遲加載壹瘟,但是必須處理好多個線程同時訪問的問題,特別是當單例類作為資源控制器鳄逾,在實例化時必然涉及資源初始化稻轨,而資源初始化很有可能耗費大量時間,這意味著出現(xiàn)多線程同時首次引用此類的機率變得較大雕凹,需要通過雙重檢查鎖定等機制進行控制殴俱,這將導致系統(tǒng)性能受到一定影響。

一種更好的單例實現(xiàn)方法

餓漢式單例類不能實現(xiàn)延遲加載枚抵,不管將來用不用始終占據內存线欲;懶漢式單例類線程安全控制煩瑣,而且性能受影響汽摹±罘幔可見,無論是餓漢式單例還是懶漢式單例都存在這樣那樣的問題逼泣,有沒有一種方法趴泌,能夠將兩種單例的缺點都克服舟舒,而將兩者的優(yōu)點合二為一呢?答案是:Yes嗜憔!下面我們來學習這種更好的被稱之為Initialization on Demand Holder (IoDH)的技術秃励。

在IoDH中,我們在單例類中增加一個靜態(tài)(static)內部類吉捶,在該內部類中創(chuàng)建單例對象莺治,再將該單例對象通過getInstance()方法返回給外部使用,實現(xiàn)代碼如下所示:

//Initialization on Demand HolderpublicclassSingleton{privateSingleton(){ ? ? ? }privatestaticclassHolderClass ? ? ? {privatefinalstaticSingleton ?instance =newSingleton(); ? ? ? }publicstaticSingletongetInstance() ? ? ? {returnHolderClass.instance; ? ? ? }publicstaticvoidmain(String args[]) ? ? ? { ? ? ? ? ? ? ?Singleton ?s1, s2;s1 = Singleton.getInstance(); ? ? ? ? ? ? ?s2 ?= Singleton.getInstance(); ? ? ? ? ? ? ?System.out.println(s1==s2); ? ? ? }}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

編譯并運行上述代碼帚稠,運行結果為:true谣旁,即創(chuàng)建的單例對象s1和s2為同一對象。由于靜態(tài)單例對象沒有作為Singleton的成員變量直接實例化滋早,因此類加載時不會實例化Singleton榄审,第一次調用getInstance()時將加載內部類HolderClass,在該內部類中定義了一個static類型的變量instance杆麸,此時會首先初始化這個成員變量搁进,由Java虛擬機來保證其線程安全性,確保該成員變量只能初始化一次昔头。由于getInstance()方法沒有任何線程鎖定饼问,因此其性能不會造成任何影響。

通過使用IoDH揭斧,我們既可以實現(xiàn)延遲加載莱革,又可以保證線程安全,不影響系統(tǒng)性能讹开,不失為一種最好的Java語言單例模式實現(xiàn)方式(其缺點是與編程語言本身的特性相關盅视,很多面向對象語言不支持IoDH)。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末旦万,一起剝皮案震驚了整個濱河市闹击,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌成艘,老刑警劉巖赏半,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異淆两,居然都是意外死亡断箫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門琼腔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瑰枫,“玉大人,你說我怎么就攤上這事丹莲」獍樱” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵甥材,是天一觀的道長盯另。 經常有香客問我,道長洲赵,這世上最難降的妖魔是什么鸳惯? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮叠萍,結果婚禮上芝发,老公的妹妹穿的比我還像新娘。我一直安慰自己苛谷,他們只是感情好辅鲸,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著腹殿,像睡著了一般独悴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上锣尉,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天刻炒,我揣著相機與錄音,去河邊找鬼自沧。 笑死坟奥,一個胖子當著我的面吹牛,可吹牛的內容都是我干的拇厢。 我是一名探鬼主播筏勒,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼旺嬉!你這毒婦竟也來了管行?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤邪媳,失蹤者是張志新(化名)和其女友劉穎捐顷,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雨效,經...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡迅涮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了徽龟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叮姑。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出传透,到底是詐尸還是另有隱情耘沼,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布朱盐,位于F島的核電站群嗤,受9級特大地震影響,放射性物質發(fā)生泄漏兵琳。R本人自食惡果不足惜狂秘,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望躯肌。 院中可真熱鬧者春,春花似錦、人聲如沸清女。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽校仑。三九已至忠售,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間迄沫,已是汗流浹背稻扬。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留羊瘩,地道東北人泰佳。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像尘吗,于是被迫代替她去往敵國和親逝她。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內容