單例模式:深潛水

單例設(shè)計模式基本上是用來控制創(chuàng)建許多對象,因此屬于家庭創(chuàng)建模式来吩。

早期的趨勢是創(chuàng)建一個馬克斯的對象,但在某些情況下,我們需要一個固定數(shù)量的對象; 這種模式是正確的,來幫助我們圈纺。 通常,我們構(gòu)造函數(shù)標(biāo)記為私有,以確保外部世界不能創(chuàng)建對象,提供了一個靜態(tài)方法,簡單地返回對象。 它創(chuàng)建一個物體只有在沒有事先創(chuàng)建内颗。

隨著時間的推移,人們意識到這種香草的實現(xiàn)單例,幾個問題,這是改善來解決這些問題。 注意,單件不對錯; 只要適合你的問題域敦腔。

在這次演講中,我們將看看不同實現(xiàn)的單例均澳。

讓我們看看類圖:

Paste_Image.png

單使用
有幾個地方是明智的使用單例模式。 例如:日志記錄符衔、緩存找前、負(fù)載平衡、配置判族、通信(IO避免表現(xiàn)不佳或遠(yuǎn)程)和數(shù)據(jù)庫連接池躺盛。 單例的Java API的一個例子是運(yùn)行時類。

單例實現(xiàn)
這是香草的方式使用一個立即加載機(jī)制,實現(xiàn)一個單例是線程安全的形帮。

public class MySingleton {
     private static final MySingleton mySingleton = new MySingleton();
     private MySingleton(){}     
     public static MySingleton getInstance(){
        return mySingleton;
     }
}

另一方面,這里有一個例子使用延遲加載機(jī)制實現(xiàn)單例槽惫。 在多線程應(yīng)用程序中,這將是一個糟糕的方法。

class MySingleton {
     private static MySingleton mySingleton;
     private MySingleton(){}
     public static MySingleton getInstance(){
           if(null == mySingleton) {
                 mySingleton = new MySingleton();
           }
           return mySingleton;
     }
}

一個多線程的方法可以避免競態(tài)條件,以確保它不會違反一個單例的哲學(xué)辩撑。 但是在下面的例子中,使整個方法“同步”并不是一個好方法,因為我們需要把鎖對象創(chuàng)建語句界斜。

class MySingleton {
     private static MySingleton mySingleton;
     private MySingleton(){}
     public synchronized static MySingleton getInstance(){      
        if(null == mySingleton) {
           mySingleton = new MySingleton();
        }
        return mySingleton;
     }
}

下面的多線程的實現(xiàn)方式可以避免競態(tài)條件,以確保它不會違反獨立的哲學(xué)和雙重檢查鎖定的幫助下使用對象級別的鎖會達(dá)到相同的。 這個實現(xiàn)保證線程安全; 但一直鎖所需的額外的對象是這不是一個很好的實踐合冀。 另一個缺點是,有人可以使用類級別鎖你的鎖的優(yōu)點是在一個不同的對象

class MySingleton {
  private static MySingleton mySingleton;
  private static final Object lock = new Object();
  private MySingleton(){}
  public static MySingleton getInstance(){
     if(null == mySingleton) {
         synchronized(lock) {
            if(null == mySingleton) {
               mySingleton = new MySingleton();
            }
         }   
     }
     return mySingleton;
  }
}

另一個multi-threaded-based實現(xiàn)(避免競態(tài)條件)的幫助下可以實現(xiàn)雙重檢查鎖定使用類級別鎖锄蹂。 在這里,將MySingleton對象標(biāo)記為不穩(wěn)定將確保變化由一個線程應(yīng)該在另一個是可見的。 這個實現(xiàn)保證線程安全水慨。

class MySingleton {
    private volatile static MySingleton mySingleton;
    private MySingleton() {}
    public static MySingleton getInstance() {
        if (null == mySingleton) {
            synchronized(MySingleton.class) {
                if (null == mySingleton) {
                    mySingleton = new MySingleton();
                }
            }
        }
        return mySingleton;
    }
}

這意味著實現(xiàn)提供了一個聰明的構(gòu)造函數(shù),將停止單合同違反使用反射得糜。

class MySingleton {
    private volatile static MySingleton mySingleton;
    //Reflection can't hack to create more than one object.
    private MySingleton() throws Exception {
        if (null == mySingleton) {
            mySingleton = new MySingleton();
        } else {
            throw new Exception("It's a singleton class; don't expect more object to get produced");
        }
    }
    public static MySingleton getInstance() throws Exception {
        if (null == mySingleton) {
            synchronized(MySingleton.class) {
                if (null == mySingleton) {
                    mySingleton = new MySingleton();
                }
            }
        }
        return mySingleton;
    }
}

這是一個非常受歡迎的實現(xiàn)使用一個靜態(tài)類,這帶來了延遲加載和線程安全的權(quán)力。

public class MySingleton {
    private MySingleton() {}
    private static class SingletonUisngInner {
        private static MySingleton mySingleton = new MySingleton();
    }
    public static MySingleton getInstance() {
        return SingletonUisngInner.mySingleton;
    }
}

在某些情況下,如果你的單例類繼承接口可克隆屬性,那么你的單例類需要格外小心,防止單例設(shè)計合同晰洒。 你的單例類應(yīng)該覆蓋的克隆方法和顯式地拋出CloneNotSupportedException朝抖。

class ClonedClass implements Cloneable {
    //Some logic
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class MySingleton extends ClonedClass {
    private MySingleton() {}
    private static class SingletonUisngInner {
        private static MySingleton mySingleton = new MySingleton();
    }
    public static OneMore getInstance() {
        return singletonUisngInner.mySingleton;
    }
    public Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }
}

另一個,我們的決賽,非常受歡迎的和智能的方法實現(xiàn)單例使用枚舉,而照顧我們到目前為止的所有問題。

public enum  EnumSingleton{
    INSTANCE;
}

有時,人們談?wù)搯渭缍鄠€jvm,讓我們觸摸谍珊。 單身意味著只有一個對象,我們非常清楚,JVM對象生命周期管理,所以一個共享對象跨多個JVM是不可能的治宣。

但是如果你需要,你可以在一個JVM中創(chuàng)建對象并分發(fā)它作為一個序列化的對象,可以使用其他JVM(但是記住,你反序列化,那么請記住,任何靜態(tài)或標(biāo)記為瞬態(tài)將無法實現(xiàn),某個地方,打破了單合同)。 你也可以嘗試使用RMI服務(wù)器對象作為單件來適應(yīng)您的需要。

學(xué)習(xí)快樂!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末侮邀,一起剝皮案震驚了整個濱河市坏怪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌绊茧,老刑警劉巖铝宵,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異华畏,居然都是意外死亡鹏秋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門亡笑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來侣夷,“玉大人,你說我怎么就攤上這事仑乌“偻兀” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵晰甚,是天一觀的道長耐版。 經(jīng)常有香客問我,道長压汪,這世上最難降的妖魔是什么粪牲? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮止剖,結(jié)果婚禮上腺阳,老公的妹妹穿的比我還像新娘。我一直安慰自己穿香,他們只是感情好亭引,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著皮获,像睡著了一般焙蚓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上洒宝,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天购公,我揣著相機(jī)與錄音,去河邊找鬼雁歌。 笑死宏浩,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的靠瞎。 我是一名探鬼主播比庄,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼求妹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了佳窑?” 一聲冷哼從身側(cè)響起制恍,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎神凑,沒想到半個月后净神,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡耙厚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年强挫,在試婚紗的時候發(fā)現(xiàn)自己被綠了岔霸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片薛躬。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖呆细,靈堂內(nèi)的尸體忽然破棺而出型宝,到底是詐尸還是另有隱情,我是刑警寧澤絮爷,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布趴酣,位于F島的核電站,受9級特大地震影響坑夯,放射性物質(zhì)發(fā)生泄漏岖寞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一柜蜈、第九天 我趴在偏房一處隱蔽的房頂上張望仗谆。 院中可真熱鬧,春花似錦淑履、人聲如沸隶垮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽狸吞。三九已至,卻和暖如春指煎,著一層夾襖步出監(jiān)牢的瞬間蹋偏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工至壤, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留暖侨,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓崇渗,卻偏偏與公主長得像字逗,于是被迫代替她去往敵國和親京郑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

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

  • 從三月份找實習(xí)到現(xiàn)在葫掉,面了一些公司些举,掛了不少,但最終還是拿到小米俭厚、百度户魏、阿里、京東挪挤、新浪叼丑、CVTE、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,240評論 11 349
  • 單例模式(SingletonPattern)一般被認(rèn)為是最簡單扛门、最易理解的設(shè)計模式鸠信,也因為它的簡潔易懂,是項目中最...
    成熱了閱讀 4,253評論 4 34
  • 酒吧夜店讓我想起一首歌:一起搖擺论寨。這首歌最能體現(xiàn)出在酒吧里的男男女女星立,搖擺著身體跟著音樂一起瘋狂的舞動。酒吧是尋歡...
    21029cbbb386閱讀 757評論 0 0
  • 昨夜秋雨倚風(fēng)悄入葬凳,今偶感絲絲涼涼意 午間詩意興起執(zhí)卷绰垂,拜讀納蘭性德雅作 容若能文能武能詩,妙筆敢愛敢恨敢歌 一代國...
    Alex0309閱讀 367評論 0 0