設計模式之單例模式

創(chuàng)建型模式(Creational Pattern)

單例模式(SingleTon)

第一種UML圖


第二種UML圖


單例模式的寫法有多種寫法,主要介紹三種:懶漢式單例,餓漢式單例,登記式單例

單例有以下特點:

1.單例類只有一個實例

2.單例類必須自己創(chuàng)建自己的唯一對象

3.單例類必須給所有其他對象提供這一實例

單例模式確保某個類只有一個實例對象,而且自行實例化并向整個系統(tǒng)提供這個實例.在計算機系統(tǒng)中,線程池,緩存,日志對象,對話框,打印機,顯卡就驅動對象都是常見的單例,這些應用都或多或少的具有資源管理器的功能.每臺計算機可以若干個打印機,但是只有一個Printer Spooler,以避免兩個打印作業(yè)同時輸出到打印機中,每臺計算機可以有若干通信端口,系統(tǒng)應當集中管理這些通信端口,以避免一個通信端口同時被兩個請求同時調用.總之,選擇單例模式就是為了避免不一致的狀態(tài).

一.懶漢模式單例

//懶漢式單例類.在第一次調用的時候實例化自己

public class Singleton {?

? ? private Singleton() {}?

? ? private static Singleton single=null;?

? ? //靜態(tài)工廠方法?

? ? public static Singleton getInstance() {?

? ? ? ? if (single == null) {? ?

? ? ? ? ? ? single = new Singleton();?

? ? ? ? }? ?

? ? ? ? return single;?

? ? }?

}


SingleTon通過將構建方法限定為private避免了類在外部的實例化,在用一個虛擬機的范圍內,Singleton的唯一實例只能通過getInstance()方法訪問

但是以上懶漢式的實現(xiàn)沒有考慮縣城安全問題,他是縣城不安全的,并發(fā)環(huán)境下很有可能出現(xiàn)多個SingleTon實例,要實現(xiàn)線程安全,有一下三種方式,都是對getInstance方法的構造,保證了懶漢式單例的線程安全,如果你第一次接觸單例模式,對線程安全不是很了解,可以先跳過下面的這三小條,去看餓漢式單例,等看完后面的再回頭考慮線程安全問題:

1.getInstance方法上加同步

publicstaticsynchronized Singleton getInstance() {

? ? ? ? ? ? if(single ==null) {? ?

? ? ? ? ? ? ? ? single =new Singleton();?

? ? ? ? ? ? }? ?

? ? ? ? ? ? return single;?

? ? }

2.雙重檢查鎖定

public static Singleton getInstance() {

? ? ? ? if (singleton == null) {? ?

? ? ? ? ? ? synchronized (Singleton.class) {? ?

? ? ? ? ? ? ? if (singleton == null) {? ?

? ? ? ? ? ? ? ? ? singleton = new Singleton();?

? ? ? ? ? ? ? }? ?

? ? ? ? ? ? }? ?

? ? ? ? }? ?

? ? ? ? return singleton;?

? ? }

3.靜態(tài)內部類

public class Singleton {

? ? private static class LazyHolder {? ?

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

? ? }? ?

? ? private Singleton (){}? ?

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

? ? ? return LazyHolder.INSTANCE;? ?

? ? }? ?

}

第三種比上面1.2都好一些,即實現(xiàn)了線程安全,又避免了同步帶來的性能影響

二.餓漢式單例

//餓漢式單例類.在類初始化時坐桩,已經自行實例化

public class Singleton1 {?

? ? private Singleton1() {}?

? ? private static final Singleton1 single = new Singleton1();?

? ? //靜態(tài)工廠方法?

? ? public static Singleton1 getInstance() {?

? ? ? ? return single;?

? ? }?

}

餓漢式再累創(chuàng)建的同事就已經創(chuàng)建好一個靜態(tài)的對象供系統(tǒng)使用,以后不再改變,所以天生的是線程安全的.

三.登記式單例

//類似Spring里面的方法瓦侮,將類名注冊潦刃,下次從里面直接獲取。

public class Singleton3 {?

? ? private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();?

? ? static{?

? ? ? ? Singleton3 single = new Singleton3();?

? ? ? ? map.put(single.getClass().getName(), single);?

? ? }?

? ? //保護的默認構造子?

? ? protected Singleton3(){}?

? ? //靜態(tài)工廠方法,返還此類惟一的實例?

? ? public static Singleton3 getInstance(String name) {?

? ? ? ? if(name == null) {?

? ? ? ? ? ? name = Singleton3.class.getName();?

? ? ? ? ? ? System.out.println("name == null"+"--->name="+name);?

? ? ? ? }?

? ? ? ? if(map.get(name) == null) {?

? ? ? ? ? ? try {?

? ? ? ? ? ? ? ? map.put(name, (Singleton3) Class.forName(name).newInstance());?

? ? ? ? ? ? } catch (InstantiationException e) {?

? ? ? ? ? ? ? ? e.printStackTrace();?

? ? ? ? ? ? } catch (IllegalAccessException e) {?

? ? ? ? ? ? ? ? e.printStackTrace();?

? ? ? ? ? ? } catch (ClassNotFoundException e) {?

? ? ? ? ? ? ? ? e.printStackTrace();?

? ? ? ? ? ? }?

? ? ? ? }?

? ? ? ? return map.get(name);?

? ? }?

? ? //一個示意性的商業(yè)方法?

? ? public String about() {? ? ?

? ? ? ? return "Hello, I am RegSingleton.";? ? ?

? ? }? ? ?

? ? public static void main(String[] args) {?

? ? ? ? Singleton3 single3 = Singleton3.getInstance(null);?

? ? ? ? System.out.println(single3.about());?

? ? }?

}

登記式單例實際上維護了一組單例類的實例,將這些實例存在一個Map(登記簿)中,對于已經登記過的實例,

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末规伐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子匣缘,更是在濱河造成了極大的恐慌猖闪,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肌厨,死亡現(xiàn)場離奇詭異培慌,居然都是意外死亡,警方通過查閱死者的電腦和手機柑爸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門吵护,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人竖配,你說我怎么就攤上這事何址。” “怎么了进胯?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵用爪,是天一觀的道長。 經常有香客問我胁镐,道長偎血,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任盯漂,我火速辦了婚禮颇玷,結果婚禮上,老公的妹妹穿的比我還像新娘就缆。我一直安慰自己帖渠,他們只是感情好,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布竭宰。 她就那樣靜靜地躺著空郊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪切揭。 梳的紋絲不亂的頭發(fā)上狞甚,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機與錄音廓旬,去河邊找鬼哼审。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的涩盾。 我是一名探鬼主播十气,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼旁赊!你這毒婦竟也來了桦踊?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤终畅,失蹤者是張志新(化名)和其女友劉穎籍胯,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體离福,經...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡杖狼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了妖爷。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝶涩。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖絮识,靈堂內的尸體忽然破棺而出绿聘,到底是詐尸還是另有隱情,我是刑警寧澤次舌,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布熄攘,位于F島的核電站,受9級特大地震影響彼念,放射性物質發(fā)生泄漏挪圾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一逐沙、第九天 我趴在偏房一處隱蔽的房頂上張望哲思。 院中可真熱鬧,春花似錦吩案、人聲如沸棚赔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽靠益。三九已至,卻和暖如春崎岂,著一層夾襖步出監(jiān)牢的瞬間捆毫,已是汗流浹背闪湾。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工冲甘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓江醇,卻偏偏與公主長得像濒憋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子陶夜,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內容

  • 單例模式屬于java設計模式的一種凛驮,最常見實現(xiàn)方式有以下幾種 懶漢、餓漢条辟、雙重檢查單例黔夭、靜態(tài)內部類單例。 單例模式...
    Java架構_師閱讀 360評論 0 0
  • 單例模式羽嫡,顧名思義本姥,指的是一個類只存在一個實例。 那么杭棵,如何保證某一個類只存在一個實例呢婚惫?對象的創(chuàng)建是通過類的構造...
    哇哇哇one閱讀 311評論 0 2
  • 一.什么是單例模式 單例模式的定義:確保一個類只有一個實例,并提供一個訪問他的全局訪問點魂爪。單例模式是幾個設計模式中...
    Geeks_Liu閱讀 2,224評論 0 10
  • 定義:一個類僅有一個實例先舷,并提供一個訪問它的全局訪問點 UML 類圖單例模式 七種方式餓漢模式public cla...
    xsp單細胞閱讀 220評論 0 0
  • 文/千年一眼 小說《迷蝶》的文案只有這么一句: “和你在一起蒋川,是我在這世上,唯一的目的粗井《疲” 這是在夢境和現(xiàn)實中,蘇...
    千年一眼閱讀 577評論 0 2