面試時(shí)候侠坎,別只會(huì)說(shuō)餓漢蚁趁,懶漢了

都2019年最后一天了,面試的時(shí)候不要還只會(huì)說(shuō)餓漢式实胸、懶漢式他嫡,顯得你很沒競(jìng)爭(zhēng)力

單例模式特點(diǎn)
  • 構(gòu)造方法私有化
  • 通過(guò)一個(gè)靜態(tài)方法去獲取其實(shí)例
  • 在全局中對(duì)象有且只有一個(gè)番官,多線程中需要考慮到線程安全
  • 在反序列化時(shí),不要被重新創(chuàng)建新的對(duì)象
面試場(chǎng)景重現(xiàn)

面試官:說(shuō)下單例模式吧
:?jiǎn)卫J椒譃轲I漢式钢属、懶漢式徘熔、DCL……balabala
面試官:還有其他的寫法嗎?
:額署咽,我平時(shí)用的比較多的就是這幾個(gè)(我之前面試都是這樣回答的啊近顷,怎么換到現(xiàn)在不行了?宁否?窒升?what?慕匠?饱须?)

單例模式的幾種寫法
1、餓漢式
public class Singleton{
      // 不管你要不要台谊,我先給你準(zhǔn)備好
      private static Singleton INSTANCE= new Singleton();
      // 構(gòu)造方法私有化
      private Singleton(){}

      // 通過(guò)一個(gè)靜態(tài)方法去獲取其實(shí)例
      public static Singleton getInstance(){
           return INSTANCE;
     }
}

很明顯上面寫的單例蓉媳,滿足了單例模式的兩個(gè)特點(diǎn),第一個(gè)構(gòu)造方法私有化锅铅,第二通過(guò)一個(gè)靜態(tài)方法去獲取其實(shí)例酪呻。餓漢式不管你要不要,我都給你初始化好盐须,有時(shí)候我只想在調(diào)用的時(shí)候才初始化怎么辦呢玩荠?那就往下面看吧~

2、懶漢式

public class Singleton{
    private static Singleton INSTANCE = null;
     // 構(gòu)造方法私有化
    private Singleton(){}

     // 通過(guò)一個(gè)靜態(tài)方法去獲取其實(shí)例
    public static synchronized Singleton getInstance(){
        if(null == INSTANCE){
            instance = new Singleton();
        }
        return INSTANCE;
    }
}

懶漢式相比餓漢式做了改變贼邓,在調(diào)用的時(shí)候再去進(jìn)行初始化阶冈,且方法上加上了synchronized關(guān)鍵字以示同步,雖然解決了餓漢式的問題塑径,但每次調(diào)用getInstance()方法的時(shí)候女坑,都會(huì)產(chǎn)生同步開銷,一兩個(gè)還好统舀,如果是好多個(gè)呢匆骗?那還是有必要優(yōu)化一下的

3、Double Check Lock(DCL)
public class Singleton {
    // 加上了volatile關(guān)鍵字(禁止指令重排序)
    private static volatile Singleton INSTANCE = null;
    // 構(gòu)造方法私有化
    private Singleton(){}

    // 通過(guò)一個(gè)靜態(tài)方法去獲取其實(shí)例
    public static Singleton getInstance() {
        if (null == INSTANCE ) { // Single Checked
            synchronized (Singleton.class) {
                if (null == INSTANCE ) { // Double checked
                    INSTANCE  = new Singleton();
                }
 
            }
        }
        return INSTANCE ;
    }
}

什么是指令重排序绑咱?volatile是什么绰筛?寫太多不想看

4、靜態(tài)內(nèi)部類
public class Singleton{

    private static class SingletonHolder{
        public static Singleton INSTANCE = new Singleton();
    }

    // 構(gòu)造方法私有化
    private Singleton(){}

    // 通過(guò)一個(gè)靜態(tài)方法去獲取其實(shí)例
    public static Singleton getInstance(){
        return SingletonHolder.INSTANCE;
    }
}

和餓漢式一樣描融,利用類加載機(jī)制來(lái)保證只創(chuàng)建一個(gè)實(shí)例,但是通過(guò)靜態(tài)內(nèi)部類的方式去創(chuàng)建的衡蚂,只要應(yīng)用中不使用內(nèi)部類窿克,JVM就不會(huì)去加載這個(gè)單例類骏庸,也就不會(huì)創(chuàng)建單例對(duì)象,從而實(shí)現(xiàn)懶漢式的延遲加載年叮。也就是說(shuō)可以把靜態(tài)內(nèi)部類單例理解成是餓漢式懶漢式的結(jié)合具被。但是,它有個(gè)致命的弱點(diǎn)只损,如果你的這個(gè)單例需要傳context一姿,它就沒辦法滿足你了。

5跃惫、枚舉
class Resource{
}
public enum SomeThing {
    INSTANCE;
    private Resource instance;
    private SomeThing() {
        instance = new Resource();
    }
    public Resource getInstance() {
        return instance;
    }
}

說(shuō)實(shí)話叮叹,枚舉的單例寫法,我是沒寫過(guò)爆存。你們呢?不研究了蛉顽,任性……

6、容器
public class SingletonManager {
    private static Map<String,Object> map=new HashMap<String, Object>();
    
    private SingletonManager(){}
    
    public static void registerService(String key,Object instance){
        if (!map.containsKey(key)){
            map.put(key,instance);
        }
    }
    
    public static Object getService(String key){
        return map.get(key);
    } 
}

這我也沒用過(guò)先较,但面試時(shí)候要會(huì)說(shuō)吧携冤,看代碼就知道了,是單例的統(tǒng)一管理類闲勺,通過(guò)一個(gè)HashMap容器去裝曾棕。使用時(shí)通過(guò)key來(lái)獲取對(duì)應(yīng)類型的對(duì)象,這種方式使得我們可以管理多種類型的單例菜循,并且在使用時(shí)可以通過(guò)統(tǒng)一的接口進(jìn)行操作翘地。

你以為完了嗎?

餓漢式债朵、懶漢式子眶、DCL、靜態(tài)內(nèi)部類的單例寫法都有可能會(huì)出現(xiàn)一個(gè)問題序芦,那就是反序列化的時(shí)候臭杰,會(huì)被重新創(chuàng)建對(duì)象。那么問題來(lái)了谚中,怎么解決呢渴杆?

public class Singleton implements Serializable {
……
 private Object readResolve() throws ObjectStreamException {
        // instead of the object we're on,
        // return the class variable INSTANCE
        return INSTANCE;
    }
}

要想寫readResolve()這個(gè)方法,請(qǐng)記得讓你的單例實(shí)現(xiàn)Serializable接口哦~

The End
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宪塔,一起剝皮案震驚了整個(gè)濱河市磁奖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌某筐,老刑警劉巖比搭,帶你破解...
    沈念sama閱讀 218,607評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異南誊,居然都是意外死亡身诺,警方通過(guò)查閱死者的電腦和手機(jī)蜜托,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)霉赡,“玉大人橄务,你說(shuō)我怎么就攤上這事⊙鳎” “怎么了蜂挪?”我有些...
    開封第一講書人閱讀 164,960評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)嗓化。 經(jīng)常有香客問我棠涮,道長(zhǎng),這世上最難降的妖魔是什么蟆湖? 我笑而不...
    開封第一講書人閱讀 58,750評(píng)論 1 294
  • 正文 為了忘掉前任故爵,我火速辦了婚禮,結(jié)果婚禮上隅津,老公的妹妹穿的比我還像新娘诬垂。我一直安慰自己,他們只是感情好伦仍,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評(píng)論 6 392
  • 文/花漫 我一把揭開白布结窘。 她就那樣靜靜地躺著,像睡著了一般充蓝。 火紅的嫁衣襯著肌膚如雪隧枫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,604評(píng)論 1 305
  • 那天谓苟,我揣著相機(jī)與錄音官脓,去河邊找鬼。 笑死涝焙,一個(gè)胖子當(dāng)著我的面吹牛卑笨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播仑撞,決...
    沈念sama閱讀 40,347評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赤兴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了隧哮?” 一聲冷哼從身側(cè)響起桶良,我...
    開封第一講書人閱讀 39,253評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沮翔,沒想到半個(gè)月后陨帆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,702評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評(píng)論 3 336
  • 正文 我和宋清朗相戀三年歧譬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了岸浑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搏存。...
    茶點(diǎn)故事閱讀 40,015評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瑰步,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出璧眠,到底是詐尸還是另有隱情缩焦,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評(píng)論 5 346
  • 正文 年R本政府宣布责静,位于F島的核電站袁滥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏灾螃。R本人自食惡果不足惜题翻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望腰鬼。 院中可真熱鬧嵌赠,春花似錦、人聲如沸熄赡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)彼硫。三九已至炊豪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拧篮,已是汗流浹背词渤。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留串绩,地道東北人缺虐。 一個(gè)月前我還...
    沈念sama閱讀 48,216評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像赏参,于是被迫代替她去往敵國(guó)和親志笼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評(píng)論 2 355

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